Soak the beans (optional but helpful): For quicker, more even cooking, cover beans with water by 2 inches and soak 6–8 hours or overnight.
Drain and rinse. If you’re short on time, use the quick soak: cover with water, bring to a boil for 2 minutes, turn off the heat, cover, and let sit 1 hour. Drain and rinse.
Sauté the aromatics: Heat olive oil in a large pot or Dutch oven over medium heat.
Add onion, carrots, and celery with a pinch of salt. Cook 5–7 minutes until softened. Stir in garlic and cook 30 seconds until fragrant.
Build the base: Add the beans, ham bone or ham hock (or diced ham), bay leaves, thyme, and smoked paprika.
Pour in the chicken broth. Scrape up any browned bits from the bottom of the pot for extra flavor.
Simmer: Bring to a gentle boil, then reduce to a low simmer. Cover partially and cook 1½–2 hours, stirring occasionally, until beans are tender and creamy.
If using pre-cooked diced ham without a bone, start checking around 75 minutes. Add water if the soup gets too thick before the beans are done.
Shred the meat: If you used a bone or hock, remove it to a board. Pull off any meat, chop it, and return to the pot.
Discard the bone and bay leaves.
Adjust texture and seasoning: For a creamier soup, mash some beans against the side of the pot or blend a cup of soup and return it. Season with salt and pepper. Finish with 1–2 teaspoons apple cider vinegar or lemon juice for brightness.
Serve: Ladle into bowls and garnish with chopped parsley.
Serve with crusty bread or cornbread for a complete meal.