Prep the spinach. If using fresh spinach, rinse well and shake off excess water. Wilt it in batches in a large dry skillet over medium heat until just softened. Transfer to a colander and cool slightly.
Squeeze out as much liquid as possible, then chop. If using frozen spinach, thaw completely and squeeze out excess moisture.
Sauté the aromatics. In a large skillet or saucepan, melt the butter over medium heat. Add the minced onion and cook until soft and translucent, about 4–5 minutes.
Stir in the garlic and cook 30 seconds, just until fragrant.
Make the roux. Sprinkle in the flour and stir constantly for 1–2 minutes. The mixture should look like damp sand and smell slightly nutty. Don’t let it brown.
Build the sauce. Gradually whisk in the warm milk, a splash at a time, whisking until smooth before adding more.
When the mixture is lump-free and slightly thick, whisk in the heavy cream. Simmer gently for 2–3 minutes until velvety.
Season well. Stir in the salt, black pepper, nutmeg, and cayenne or white pepper if using. Taste and adjust.
The sauce should be well seasoned at this point.
Add the spinach. Fold in the chopped spinach, breaking up any clumps. Stir until the spinach is evenly coated and heated through, 2–3 minutes.
Finish with cheese. Reduce heat to low and stir in the Parmesan until melted and smooth. If the mixture is too thick, splash in a bit more milk or cream; if too loose, let it gently simmer a minute to tighten up.
Serve hot. Spoon into a warm serving dish.
For a steakhouse touch, top with a small pat of butter or a sprinkle of extra Parmesan.