Peel your onions and slice them evenly. You don’t want super thin slivers or chunky half-moons, just aim for consistent slices so they cook evenly.
In a large Dutch oven or heavy-bottomed pot, melt butter with olive oil over medium heat. Add the onions and give them a good stir to coat them in the buttery goodness.
At first, they’ll just soften and turn translucent, this takes about 15 minutes. Then, lower the heat to medium-low and let them cook slowly for another 30–40 minutes, stirring occasionally. Don’t rush this! Caramelized onions need time to develop that deep golden-brown sweetness.
In the last few minutes, toss in the garlic (just don’t let it burn).
Now crank up the heat to medium-high and pour in the wine. Use a wooden spoon to scrape up all the flavorful browned bits from the bottom of the pot. Let the wine reduce by half, it’ll take around 5 minutes. This adds a tangy depth that balances the sweetness of the onions.
Stir in the beef stock, bay leaves, thyme, plus a pinch of salt and pepper. Bring everything to a gentle simmer, then lower the heat and let it bubble quietly for 30 minutes. Your kitchen will smell incredible at this point, and the soup will be rich and full of flavor. Don’t forget to fish out the bay leaves before serving.
Preheat your broiler. Place baguette slices on a baking sheet, top them with shredded Gruyère cheese, and broil until bubbly and golden brown, about 2–3 minutes. Watch closely, because they can go from golden to burnt in a heartbeat!
Ladle the soup into bowls, carefully place the cheesy baguette slices on top, and serve immediately. Grab a spoon, break through that melty cheese layer, and enjoy every bite.