Peel and thinly slice the onions, keeping the slices consistent for even caramelization.
Heat a wide, heavy-bottomed sauté pan over medium-low heat and add the butter and olive oil. Once melted and fragrant, add the sliced onions and a pinch of salt.
Cook the onions slowly, stirring every 8-10 minutes, until they turn a deep golden brown and smell sweet, about 45-60 minutes. The onions will become soft, fragrant, and dark amber in color.
Pour in the white wine to deglaze the pan, scraping up any browned bits from the bottom. Let the wine reduce by half, about 3-4 minutes, until the mixture is fragrant and slightly syrupy.
Add the broth, thyme sprig, and bay leaf to the pan. Bring to a gentle simmer and cook uncovered for 20 minutes, allowing the flavors to meld and intensify. Skim off any foam or impurities that rise to the surface.
Remove the thyme sprig and bay leaf. Taste the soup and season with salt and pepper as needed.
While the soup simmers, slice the baguette into ½-inch rounds and toast them on a baking sheet at 180°C (350°F) until golden and crispy, about 10 minutes.
Preheat the broiler or oven grill. Ladle the hot soup into ovenproof bowls, then top each with a toasted baguette slice and a generous sprinkle of grated Gruyère cheese.
Place the bowls under the broiler until the cheese bubbles and turns golden brown, about 2-4 minutes. Keep a close eye to prevent burning.
Carefully remove the bowls from the oven and let rest for 2 minutes. Serve hot, garnished with a little extra thyme if desired.