Slice the onions thinly. In a large pot, melt the butter and olive oil over medium heat. Add the onions and a pinch of salt. Cook, stirring frequently, for about 20-25 minutes until the onions are caramelized and golden brown.
Add minced garlic to the onions and cook for an additional minute.
Pour in the beef broth, and add thyme, bay leaf, salt, and pepper. Bring to a boil, then reduce the heat and let it simmer for about 15 minutes.
While the soup is simmering, prepare the meatballs. In a bowl, mix ground beef, egg, breadcrumbs, Worcestershire sauce, garlic, salt, and pepper. Form into small meatballs (about 1-inch in diameter).
In a skillet over medium heat, cook the meatballs for about 5-7 minutes until they are browned on all sides.
Add the browned meatballs to the soup and let simmer for another 10 minutes.
Preheat the oven to broil. While the soup is finishing, place the slices of French bread on a baking sheet and toast under the broiler until golden brown, about 1-2 minutes each side.
To serve, ladle the soup into bowls, place a slice of toasted bread on top of each bowl, and sprinkle generously with Gruyère cheese.
Broil the assembled bowls for 1-2 minutes until the cheese is bubbly and slightly browned.
Remove from the oven and let cool for a minute before serving.