Melt butter in a large pot over medium heat. Add the onion and cook for 4 to 5 minutes until soft. Stir in garlic and cook 30 seconds.
Sprinkle in flour and cook for 1 minute, stirring constantly.
Add in broth and macaroni. Bring to a boil. Stir often, or it will stick.
Reduce heat to medium-low and cook uncovered for 8 to 10 minutes, stirring often, until pasta is tender.
Stir in the cheeses, milk, half-and-half, Dijon, paprika, salt, and pepper. Heat for an additional 5 minutes or until it’s hot. Taste and adjust seasoning before serving.
Notes
Stir the pasta often while it cooks, so it doesn’t stick to the bottom of the pot.
Keep the heat low once you add the milk and cheese to prevent curdling or a grainy texture.
Shred your own cheese for the smoothest, creamiest result.
If the soup gets too thick, stir in a splash of milk or broth before serving.
The soup will thicken as it sits, especially in the fridge, so plan to add a little liquid when reheating.
Taste and adjust seasoning at the end since cheese and broth can vary in saltiness.
For the best texture, serve right after cooking while it’s hot and creamy.