---
title: "Ingredient substitutions: buttermilk, eggs, lime zest and more — Tiny Plates"
description: "Ingredient substitutions with real amounts: buttermilk, eggs, lime zest, self-raising flour and more, plus a free API that returns ratios and cautions."
url: "https://www.tinyplates.dev/blog/ingredient-substitutions"
---

# Ingredient substitutions: out of buttermilk, eggs or lime zest?

A table of swaps with real amounts, and how to add them to your own recipe app.

25 October 2026

You're halfway into pancakes and the buttermilk is gone. Or the cake wants two eggs and you have one. Or the recipe says "zest of 1 lime" and the fruit bowl only has lemons. It happens to everyone.

Most of the time there's a good swap. The trick is knowing how much to use, and when the swap will let you down. Olive oil is a fine stand-in for butter in a pan sauce. In pastry it's a disaster.

So here's a table of common swaps, with amounts. Most of it comes straight from the substitutions data behind the Tiny Plates API. A few rows, like zest, self-raising flour and herbs, aren't in our data yet. For those we used the [In a Pinch substitution chart](https://pubs.nmsu.edu/%5Fe/E131/) from New Mexico State University's extension service, which is the kind of boring, tested source you want for this.

| Out of             | Use instead                     | How much                                                                | When it doesn't work                                     |
| ------------------ | ------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------- |
| Buttermilk         | Milk and lemon juice            | 1 tbsp lemon juice in 240 ml (1 cup) milk, left for 10 minutes          | Works for pancakes, scones and cakes                     |
| Egg                | Ground flaxseed and water       | 1 tbsp flaxseed and 3 tbsp water per egg, left to thicken               | Not for meringue, mousse or anything with whipped whites |
| Egg                | Apple sauce                     | 60 ml (1/4 cup) per egg                                                 | Binds but doesn't lift, so not for a sponge              |
| Lime zest          | Lemon zest                      | Same amount                                                             | A little rounder and less sharp, but close               |
| Zest of 1 lemon    | Dried lemon peel                | About 1 tsp                                                             | Fine in baking, weaker as a garnish                      |
| Zest of 1 lemon    | Lemon extract                   | About 1/2 tsp                                                           | Strong, so go easy                                       |
| Lime juice         | Lemon juice                     | Same amount                                                             | Rounder and less floral                                  |
| Sour cream         | Greek yogurt                    | Same amount                                                             | Leaner and a bit tangier                                 |
| Crème fraîche      | Sour cream                      | Same amount                                                             | Fine in most dishes                                      |
| Butter             | Olive oil                       | Three quarters as much                                                  | Not for creaming into a batter or for pastry             |
| Butter             | Block margarine                 | Same amount                                                             | Use a block, not a spread. Spreads carry more water      |
| Self-raising flour | Plain flour and baking powder   | 1 cup minus 2 tsp plain flour, 1 1/2 tsp baking powder and 1/2 tsp salt | Mix it well so the rise is even                          |
| Baking powder      | Baking soda and cream of tartar | 1/4 tsp soda and 1/2 tsp cream of tartar per tsp                        | Use it at once                                           |
| Cornstarch         | Plain flour                     | Twice as much                                                           | The sauce is cloudier and tastes faintly of flour        |
| Red wine           | Grape juice and vinegar         | 1 tbsp red wine vinegar in 240 ml juice                                 | Sweeter, so taste as you go                              |
| Red wine           | Beef stock                      | Same amount                                                             | Loses the acidity. Add a splash of vinegar back          |
| White wine         | Chicken stock                   | Same amount                                                             | Loses the acidity the wine brought                       |
| Fresh herbs        | Dried herbs                     | 1 tsp dried per 1 tbsp fresh, finely cut                                | Best in things that cook a while, not as a garnish       |
| Garlic clove       | Garlic powder                   | 1/8 tsp per clove                                                       | Not where the garlic is fried, roasted or left whole     |
| Shallot            | Onion and garlic                | Half a small onion and a small clove per shallot                        | Fine in cooked dishes                                    |
| Brown sugar        | Sugar and molasses              | 1 tbsp molasses in 200 g white sugar                                    | Close enough for cookies                                 |
| Honey              | Maple syrup                     | Same amount                                                             | Thinner, with its own flavour                            |

A couple of notes on the trickier ones.

Zest is all about the oils in the peel, not the sourness. That's why lemon juice is a poor swap for zest: you get the sour without the smell. If a recipe wants lime zest and you have a lemon, zest the lemon. If you only have juice, use a little and accept it'll taste different. The NMSU chart puts the zest of one medium lemon at about 1 to 2 teaspoons, which is handy when a recipe says "zest of 1 lemon" and you're using dried peel.

Self-raising flour is mostly a British and Australian thing. If you bake from UK recipes in grams, a common home mix is 2 teaspoons of baking powder per 150 g of plain flour, which is what [Silver Spoon](https://www.silverspoon.co.uk/baking-tips/how-to-turn-plain-flour-in-to-self-raising-flour) suggests too. Sift them together so you don't get pockets of powder.

Egg swaps are the ones that fool people most. An egg does a few jobs at once. It binds, it lifts and it sets. Flaxseed and apple sauce are good at binding. They're no help with lift. So they work in brownies, muffins and pancakes, and they fail in a sponge or a soufflé. If a recipe has three or more eggs, a swap usually won't save it. Find a recipe that's egg-free on purpose.

One more thing. A swap isn't an allergy check. Some margarines contain milk. Some stock cubes contain celery or wheat. If you're swapping because of an allergy, read the label on the new thing too.

## Substitutions in your own app

If you're building a recipe app, swaps are a lovely feature. Someone opens a recipe, sees "buttermilk", and you can say "out of it? Here's what to use". It keeps them cooking instead of bouncing to a search engine.

The hard part is that a good swap depends on the dish. Olive oil for butter is fine in a sauce and bad in pastry. Greek yogurt for mayonnaise is fine in a dip and splits in a hot dish. A flat list of "X = Y" lines hides that. So our data carries it along with each swap.

You ask `/substitutions` with a comma-separated list of ingredient names or ids, up to 20 at a time:

```bash
curl 'https://api.tinyplates.dev/substitutions?ingredients=buttermilk,butter,lime%20zest' \
  -H 'Authorization: Bearer rd_your_api_key'

```

And you get this back:

```json
{
  "substitutions": [
    {
      "ingredient": "buttermilk",
      "options": [
        {
          "ingredient": "milk and lemon juice",
          "note": "Stir 1 tbsp of lemon juice into 240 ml of milk and leave it to thicken for ten minutes.",
          "ratio": 1
        }
      ]
    },
    {
      "ingredient": "butter",
      "options": [
        {
          "caution": "Not for creaming into a batter or for pastry, where solid fat is what makes the texture.",
          "ingredient": "olive oil",
          "note": "Use three quarters as much. The result is softer and does not brown the same way.",
          "ratio": 0.75
        },
        {
          "ingredient": "margarine",
          "note": "Use a block, not a spread: spreads carry more water.",
          "ratio": 1
        }
      ]
    }
  ],
  "unknown": ["lime-zest"]
}

```

Each option has four fields. `ingredient` is what to use. `ratio` is how much of it to use for one unit of the original, so 0.75 means three quarters as much. `note` says how to prepare it, and is only there when there's something to say. `caution` says what the swap can't be used for. It only shows up when the swap changes the dish in a way the cook needs to know about.

Look at the last line too. We don't have lime zest in our data yet, so it comes back in `unknown` instead of with a guess. That's on purpose. A plausible wrong number is worse than no answer, especially mid-recipe. In your app, `unknown` is your cue to say "no swap we're sure about" rather than make one up.

Names are tidied up before lookup, so "lime zest" becomes `lime-zest`. You can also send the canonical ids that recipes use in their `ingredientId` field. Common spellings point to the same advice, so "unsalted butter" gets the butter swaps and "heavy cream" gets the cream ones.

Here's a small helper that takes an ingredient line from a recipe and turns the swaps into something you can show:

```ts
interface Quantity {
  unit?: string
  value: number
}

interface Swap {
  caution?: string
  ingredient: string
  note?: string
  ratio: number
}

async function swapsFor(ingredientId: string, quantity?: Quantity) {
  const url = new URL('https://api.tinyplates.dev/substitutions')
  url.searchParams.set('ingredients', ingredientId)

  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.TINY_PLATES_API_KEY}` }
  })
  const body = await response.json()

  const options: Swap[] = body.substitutions[0]?.options ?? []

  return options.map((swap) => ({
    amount: quantity
      ? `${Math.round(quantity.value * swap.ratio * 100) / 100} ${quantity.unit ?? ''}`.trim()
      : undefined,
    caution: swap.caution,
    name: swap.ingredient,
    note: swap.note
  }))
}

// 2 tbsp butter → "1.5 tbsp olive oil", with the pastry warning attached
const swaps = await swapsFor('butter', { unit: 'tbsp', value: 2 })

```

Two tips from building this ourselves. First, always show the `caution` when there is one. It's short, and it's the part that saves the dish. Second, show the `note` next to mixed swaps like "milk and lemon juice". The ratio tells you how much of the mix to use. The note tells you how to make it.

Recipes come scaled and converted already if you ask for them that way, so the amount you multiply is the one the cook sees. There's more on that in [scaling recipes](https://www.tinyplates.dev/blog/scaling-recipes) and [cups to grams](https://www.tinyplates.dev/blog/cups-to-grams).

This pairs nicely with allergens. When a recipe has something a user can't eat, you could hide it. Or you could offer a swap and keep a good recipe on the table. Our post on [allergen data](https://www.tinyplates.dev/blog/allergen-data-for-every-recipe) covers the filtering side. Just remember the label point from earlier. A swap changes the ingredient, not the packet it comes in.

Agents get this too. The [Tiny Plates MCP server](https://www.tinyplates.dev/blog/tiny-plates-mcp-server) has a `find_substitutions` tool, so you can ask your assistant "I'm out of buttermilk, what can I use in these pancakes?" and it answers from the same data.

If you're already on Spoonacular, it has an ingredient substitutes endpoint as well, and it's worth a look. Its answers come back as lines of text, so you'd parse out the amounts yourself. Ours is smaller but structured, with the ratio and the warnings as separate fields.

The full reference is on the [substitutions docs page](https://www.tinyplates.dev/docs/api/substitutions). It's free, with 50 requests a day. [Grab a key](https://www.tinyplates.dev/sign-up) if you want to try it.
