Prepare the Meatballs
Make homemade meatballs according to your preferred recipe or use thawed frozen meatballs according to package directions. If making homemade, ensure they are fully cooked through before adding to the soup. Set aside until ready to use.
Sauté the Aromatics
Heat the olive oil in a large pot or Dutch oven over medium heat. Add the diced onion with a pinch of salt and pepper, and cook until lightly caramelized, about 6-8 minutes. Add the minced garlic, Italian seasoning, and tomato paste, and cook for another minute until fragrant and the tomato paste darkens slightly.
Build the Soup Base
Add a splash of chicken broth to the pot and use a wooden spoon to scrape up any flavorful browned bits from the bottom. Then add the remaining chicken broth, crushed tomatoes, uncooked rotini pasta, and prepared meatballs to the pot.
Simmer Until Tender
Bring the soup to a simmer, then reduce heat to medium-low. Cover the pot and cook for 12-15 minutes, or until the pasta is al dente and the meatballs are heated through. Stir occasionally to prevent the pasta from sticking to the bottom.
Finish and Serve
Stir in the baby spinach and heavy cream until the spinach wilts, about 1-2 minutes. Taste and adjust seasoning with additional salt and pepper if needed. Ladle the soup into bowls and garnish with shaved Parmesan cheese and chopped fresh parsley before serving.