Before you start, rinse your rice under cold water until the water runs clear, then set it aside. Measure out your broth and have all your ingredients prepped. This recipe moves quickly once the ham hits the pan.
Brown the ham. Heat a drizzle of oil in a wide, heavy-bottomed pan over medium heat. Add the diced ham and cook, stirring occasionally, until it picks up some color and the fat begins to render, about 3-4 minutes. The fond (the brown bits sticking to the pan) is flavor, don't discard it.
½ oz ham, 1 tablespoon olive oil
Add the onions. Add the diced onion to the pan with the ham and saute together until the onions are translucent and soft, about 4-5 minutes. They'll absorb all the rendered ham fat and start to smell incredible.
1 small onion
Add the beans. Add the beans directly to the pan and stir them into the ham and onion mixture. Let them sit in the pan for a minute or two so they can absorb the fond on the bottom.
1 cup rehydrated beans
Season the beans. Add the sofrito, garlic paste, and adobo. Stir everything together and cook for 2-3 minutes so the sofrito has a chance to bloom in the hot pan and cook off its raw edge.
Add the rice and achiote oil. Add the rinsed rice and the achiote oil to the pan. Stir and toss to coat the rice grains in the oil and distribute everything evenly. You'll see the rice start to take on that golden color immediately.
1 cup rice, 2 tablespoon achiote oil
Measure the broth. Use a 1:1:1 ratio of rice to beans to liquid. The rule is for every cup of rice, use a cup of liquid. Have it measured and ready before the rice goes in so you're not scrambling.
1 cup broth
Add the broth and bring to a boil. Pour in the broth. Stir once to combine, then bring to a boil over medium-high heat. Let it boil uncovered for about 5 minutes. Do not stir. You're waiting for most of the liquid to absorb down to the level of the rice.
Reduce the heat and cover. Once it has reduced to just below the surface of the rice, reduce the heat to the lowest setting, cover tightly, and let it steam for 15 minutes. Do not lift the lid during this time; the steam is doing the work.
Check for doneness. After 15 minutes, remove the lid. The rice should be fully cooked, with no visible liquid remaining. If there's still liquid, cover and cook for another 3-5 minutes at low heat. The rice at the bottom may form a slight crust, called pegao, and in Puerto Rico, it's the craze.
Fluff and serve. Use a fork (never a spoon) to gently fluff the rice from the bottom up. This separates the grains without mashing them. Serve immediately, garnished with sliced avocado if you like.
Notes
The ratio is everything: 1 cup rice, 1 cup beans, and 1 cup liquid. Too much liquid and you end up with sticky, wet, gummy rice. Not enough, and the bottom scorches before the top cooks through. Stick to the ratio, don't lift the lid during the steam, and you'll get loose, separate, perfectly cooked grains every time.
Pan choice matters: The traditional pot of choice for rice in Puerto Rico is el caldero. I don't have a caldero, and I like to use my Tramontina sauce pot or a Lodge Dutch Oven when I want to make larger quantities.
Don't skip browning the ham first: That initial sear creates fond on the bottom of the pan that seasons everything that follows. If you add all the ingredients at once, it creates steam, and the ham and vegetables will not develop fond and caramelization, which deepens the flavors.
Use broth whenever possible: Water always works, but broth is noticeably better. It would be the same as using a bouillon cube. Chicken broth is the most neutral and complementary, but vegetable broth is excellent for a vegetarian version.
Storage:
Store leftover arroz con habichuelas in an airtight container in the refrigerator for up to 4 days. Reheat in a covered pan with a splash of broth or water to restore moisture.
Freezing: Arroz con habichuelas freezes well for up to 2 months. Freeze in individual portions for easy weeknight meals. Thaw overnight in the refrigerator, then reheat, covered, with a little liquid added.