In a large pot or Dutch oven, heat the butter and olive oil over medium heat. Add the sliced onions and cook, stirring occasionally, for about 30-40 minutes. Be patient during this step to allow the onions to caramelize and turn a rich golden brown. Stir occasionally to avoid burning.
Once the onions are caramelized, add the minced garlic and cook for 1 minute. Pour in the white wine to deglaze the pan, scraping up any browned bits from the bottom. Let the wine cook off for about 2-3 minutes.
Add the beef or vegetable broth, thyme, bay leaves, salt, and pepper. Bring the soup to a simmer and cook for 20-30 minutes to allow the flavors to meld together. Taste and adjust the seasoning if needed.
Preheat your oven. Brush the bread slices with olive oil or butter and toast them in the oven until golden brown, about 5 minutes per side. Set aside.
Remove the bay leaves and thyme sprigs from the soup. Ladle the soup into 4 oven-safe bowls or crocks. Place a slice of toasted bread on top of each bowl of soup and cover with grated Gruyère cheese. Sprinkle with Parmesan cheese for extra flavor.
Place the bowls under the broiler for about 3-5 minutes, or until the cheese is golden, bubbly, and melted. Keep an eye on it to prevent burning.
Carefully remove the bowls from the oven and serve the soup immediately. Garnish with fresh or dried thyme if desired.