Vietnamese Xiu Mai Meatballs in Tomato Sauce

Vietnamese Xiu Mai Meatballs in Tomato Sauce

These Vietnamese-style pork meatballs are bound with soaked baguette crumbs and seasoned boldly with fish sauce and shallots. Browned until golden, they simmer gently in a rich, savory tomato sauce infused with caramelized shallots and garlic. The result is tender, flavorful meatballs in a concentrated sauce perfect for rice or crusty bread.

Prep
20 min
Cook
20 min
Wait
25 min
Total
1 hr 5 min
Makes
About 20–24 meatballs (serves 4 as a main course, or 6 as part of a larger meal)
Share

Steps

Before you start
  • Use day-old or stale baguette for the best tender texture—fresh bread will become mushy
  • Measure and prep all ingredients before forming the meatballs so you can work quickly
  • Make sure you have a large 12-inch (30 cm) skillet to brown meatballs without crowding
  • Do not overwork the meatball mixture when mixing; this keeps them light and tender
  1. Prepare the breadcrumbs

    • Tear the 2 oz day-old baguette into 1-inch pieces and place in a small bowl.
    • Pour the 3 tbsp water over the bread and let sit for 2–3 minutes to soften.
    • Gently squeeze the soaked bread with your hands to release excess moisture—the bread should feel like a moist paste, not soggy.
    + Show details

    Ready when: Bread is moistened and easily squeezable into a paste

    Tip: Day-old or stale baguette is essential—fresh bread becomes mushy and ruins the texture of the meatballs

  2. Mix the meatball filling

    • In a large bowl, combine the ground pork, prepared breadcrumbs, minced shallots, minced garlic, fish sauce, egg, salt, and pepper.
    • Using your hands, gently fold and mix until just combined—aim for a few strokes, not complete uniformity.
    • Do not overwork the mixture; this keeps the meatballs tender and light.
    + Show details

    Tip: Mix gently and quickly—overworking the meat develops gluten-like proteins and makes dense, tough meatballs

  3. Form the meatballs

    • Using your hands or a small 1.5-tablespoon scoop, form the mixture into 20–24 meatballs about 1.5 inches (4 cm) in diameter.
    • Place them on a plate or parchment paper as you form them.
    • Lightly wet your hands with water to prevent the mixture from sticking as you work.
    + Show details

    Ready when: All meatballs are formed and roughly uniform in size

    Tip: Wet hands help prevent sticking—rewet as needed. Consistent sizing helps them cook evenly

  4. Brown the meatballs

    • Heat 2 tbsp oil in a large 12-inch (30 cm) skillet over medium-high heat until shimmering, about 2 minutes.
    • Working in batches of 8–10 meatballs to avoid crowding, carefully add them to the hot pan.
    • Brown on all sides, turning occasionally, for 8–10 minutes total.
    • Transfer browned meatballs to a clean plate.
    • Don't be concerned if they're still slightly pink inside—they'll finish cooking in the sauce.
    + Show details

    Ready when: Meatballs are golden brown on all sides

    Tip: Don't overcrowd the pan—each meatball needs space so it browns properly instead of steaming

  5. Make the sauce base

    • In the same skillet (don't wash it), add the sliced shallots.
    • Cook over medium heat, stirring occasionally, for 3–4 minutes until softened and lightly golden—you're building depth of flavor here.
    • Add the minced garlic and cook for 30 seconds more, stirring constantly, until fragrant.
    + Show details

    Ready when: Shallots are soft and beginning to caramelize; garlic is fragrant

  6. Add tomatoes and liquid

    • Pour in the 28 oz can of crushed tomatoes, 1 cup of water or chicken broth, 1 tbsp fish sauce, 1 tsp sugar, and 1/2 tsp salt.
    • Stir well, using a wooden spoon to scrape up any browned bits (called fond) stuck to the bottom of the pan—these add tremendous depth of flavor.
  7. Return meatballs and simmer

    • Gently return all the browned meatballs to the skillet, nestling them into the sauce.
    • The sauce should cover most of the meatballs.
    • Bring to a simmer over medium heat, then reduce heat to medium-low.
    • Partially cover the pan with a lid and simmer gently for 20–25 minutes, stirring occasionally, until the meatballs are cooked through.
    + Show details

    Ready when: Meatballs are cooked through to an internal temperature of 160°F (71°C), and the sauce has thickened slightly

  8. Finish and serve

    • Remove the skillet from heat.
    • Taste the sauce and adjust seasoning with additional salt, pepper, or fish sauce as needed.
    • Serve the meatballs and sauce over steamed jasmine rice or with crusty bread for soaking up the sauce.
    • Garnish with fresh cilantro and sliced green onions if desired.

Good to know

Tips
  • Don't overwork the meatball mixture when mixing—gently combine until just combined. Overmixing leads to dense, tough meatballs.
  • Browning the meatballs first creates a golden crust that locks in flavor and develops deeper, richer tastes in the sauce.
  • Keep the heat at medium-low when simmering—a rolling boil can cause the meatballs to break apart and become tough.
  • These meatballs pair beautifully with steamed jasmine rice, crusty French bread, or soft rice noodles to soak up every bit of the savory sauce.
Make ahead

Meatballs can be formed up to 24 hours ahead, covered with plastic wrap and refrigerated. You can also brown and freeze them for up to 3 months in an airtight container; thaw in the refrigerator overnight, then simmer in the sauce from frozen, adding 5–10 extra minutes to simmering time.

Storage & reheating

Room temperature (up to 2 hours): Store in an airtight container; reheat gently in a skillet over medium heat, stirring occasionally. Refrigerator (3–4 days): Store in an airtight container. Reheat in a skillet over medium heat, stirring often, or in the microwave at 50% power. Freezer (up to 3 months): Freeze in an airtight container or freezer bag. Thaw in the refrigerator overnight, then reheat gently over medium heat.

Substitutions
  • ground pork → Ground beef. Use the same weight (1.5 lbs / 680g). Beef will give a slightly deeper, richer flavor. Cook to the same internal temperature of 160°F (71°C).
  • baguette → Panko breadcrumbs. Use 1/3 cup (35 g) panko mixed with 3 tbsp water instead of soaked baguette. The texture will be slightly less tender, but flavor remains strong.
  • canned crushed tomatoes → Fresh tomatoes. Use 2 lbs (900 g) fresh tomatoes, peeled, seeded, and chopped. You may use slightly less broth (3/4 cup instead of 1 cup) since fresh tomatoes release more liquid.
  • fish sauce → Soy sauce plus Worcestershire sauce. Replace the 2 tbsp fish sauce in meatballs with 1 tbsp soy sauce + 1 tbsp Worcestershire sauce. The umami depth will be slightly different but still satisfying.

More meatballs

See all →

Find more like this

Meal
Dinner
Cuisine
Vietnamese
Main ingredient
Ground Pork
Method
Stovetop

Reviews (0)