Ingredients
Method
Make the Meatball Mixture
- In a large bowl, combine ground beef, grated Parmesan, breadcrumbs, egg, minced garlic, parsley, salt, pepper, and oregano. Mix gently — overworking makes dense meatballs.
- Form into small meatballs, about 1 to 1 1/4 inches across. You should have roughly 20–24 meatballs.
Brown the Meatballs
- Heat 1 tbsp olive oil in a large Dutch oven or deep skillet over medium-high heat.
- Brown the meatballs in batches for 2–3 minutes per side until they have a golden crust. They don’t need to be fully cooked through. Transfer to a plate and set aside.
Build the Soup Base
- In the same pot, add 1 tbsp olive oil if needed. Sauté the onion, carrots, and celery over medium heat until softened, about 6–8 minutes.
- Add the garlic and cook for 30–60 seconds until fragrant.
Add Tomatoes, Broth, and Beans
- Pour in the crushed tomatoes and broth, scraping up any browned bits from the bottom of the pot.
- Stir in the drained beans, Parmesan rind, dried basil, and red pepper flakes if using. Bring to a gentle simmer.
Simmer with Meatballs
- Return the browned meatballs to the pot. Simmer for 12–15 minutes, until meatballs are cooked through and the flavors have melded.
- Taste and adjust salt and pepper. If you want a silkier texture, lightly mash some beans against the side of the pot with a spoon.
Finish and Serve
- Stir in baby spinach until wilted, if using.
- Ladle into bowls and top with freshly grated Parmesan and chopped parsley. Serve with crusty bread for dunking.
Notes
Make-ahead: You can form meatballs and refrigerate them overnight. Cook from chilled and add a few extra simmer minutes. Use store-bought frozen meatballs to save time. Vegetarian option: Swap meatballs for roasted chickpeas or store-bought plant-based meatballs. If you're grilling vegetables, they pair beautifully with the soup.