"Is it cheaper to cook this or order in?" is the question that decides a lot of weeknights — and most meal-planning apps have no answer. They plan, they list, they cook. They never put a number on it. We checked the field: per-serving cost shows up only in scattered single-purpose tools (a receipt tracker here, a manual calculator there), never built into the plan itself. Hearth builds it in.
A price on every recipe — as a range
Every Hearth recipe shows a cost per serving. We show it as a range, on purpose, because the real cost depends on whether you use everything you buy:
- Low — amortized. You use exactly what the recipe needs and the rest gets used up elsewhere. This is the true cost of the food that went into the plate.
- High — as bought, with waste. For fresh perishables, the smallest package is bigger than the recipe needs, and the part you can't finish before it spoils is money in the bin. The high end counts that.
The gap between those two numbers is the waste — and shrinking it is exactly what planning a week (instead of one meal) is for. A single recipe is stuck with the package size; a week's plan can route the leftover half-bunch of cilantro into a second dinner.
The bulk trap most budgets fall for
Bigger packages have a lower price per gram — so they look cheaper. For shelf-stable things (rice, canned tomatoes) that's a pure win. For perishables it's often a trap: the 1 kg box of spinach is cheaper per gram than the 200 g bag, but if your week only uses 200 g, you paid more and threw the rest away.
Because Hearth knows the amount your plan will actually use, it can measure the number that matters:
Effective cost = what you pay for the package ÷ the amount you actually use. By that measure the small bag is frequently the cheaper buy — and Hearth can tell you when, instead of letting the shelf sticker fool you.
A worked example: Lazy Lasagna
Rather than describe the method, here is one whole recipe with its arithmetic showing. These figures are computed live by the same code that prices every recipe in the app — so this table cannot drift away from the number on the recipe card.
| Amount | Ingredient | Cost |
|---|---|---|
| 1 lb | Ground Beef | $7.94 |
| 1 tub | Cottage Cheese | $5.49 |
| 2 cups | Mozzarella | $4.48 |
| 1 jar | Pasta Sauce | $3.75 |
| 9 | Lasagna Noodles | $1.43 |
| 2 | Eggs | $0.82 |
| 1/4 cup | Parmesan Cheese | $0.68 |
| 1/3 cup | Parsley | $0.55 |
| 1 tsp | Onion Powder | $0.14 |
| 1/2 tsp | Basil | $0.04 |
| 1/8 tsp | Black Pepper | $0.01 |
| 1/4 cup | Water | $0.00 |
| Total for 4 servings | $25.32 | |
| Per serving | $6.33–$7.15 |
The single line that moves this dish is the ground beef. That is why a sale on it flags the recipe and a sale on the black pepper does not. The higher figure is the same meal bought as whole packages, counting the part of the perishables a single dinner can't finish — the gap between the two numbers is the waste. Every ingredient here is priced from real data, with nothing falling back to a category average. Water is in the table at $0.00, priced from municipal rates, because leaving it out would have been a small lie about completeness.
Where the prices come from
Hearth's prices are in Canadian dollars, drawn from Canadian sources — Statistics Canada's food price data for staples, refreshed retail pricing for meat and other cost-dominant items, plus current flyer pricing for what's on sale. Most of the big meal-planning apps are price-blind entirely.
What the number is, precisely. The figure we show is a range, and its low end is a floor — that is why it reads "from $X" rather than a single confident number. Statistics Canada figures are national monthly averages, which typically sit below what you pay in a given store on a given week. Meat and the other items that dominate a bill are priced against refreshed retail, so the expensive part of the estimate is the grounded part. Treat it as a reliable way to compare two dinners, and as a floor rather than a promise for your total bill.
Every ingredient is counted, and we tell you how much of it is real. Where we hold a genuine price for an ingredient we use it. Where we don't, we fall back to a category average for that aisle rather than counting the ingredient as free — a recipe with an unpriced item should not look cheaper than one without. We track what fraction of each recipe is priced from real data, and if that falls below half we show no figure at all instead of a confident-looking guess. Today that fraction is 90% or better on the overwhelming majority of our recipes.
If we don't know where you are, you get a national estimate — not one city's prices wearing your city's name. And if we know you're somewhere we don't have data for yet, we'd rather show you nothing than a number from the wrong country.
"On sale this week" — turned into dinners
Hearth reads the weekly flyers for stores near your postal code and flags the recipes whose cost-dominant ingredient is advertised right now, and which store has the best price. Instead of "chicken is on sale somewhere," it's "here are three dinners that got cheaper this week, and where to buy." The cost-dominant part matters: a sale on basil doesn't move a lasagna, so it doesn't earn a badge.
An honest limit, because it is the sort of thing most apps leave out. A flyer item is an advertised item, and advertised is not always discounted. Only a minority of flyer items print their own regular price — for those we check the sale price really is lower, and drop it if it isn't. For the rest we can only tell you the store is featuring it this week at this price. We say "on sale" because that is what the flyer says; where we have been able to verify a genuine discount, we show the percentage, and where we haven't, we don't.
We only show flyer prices for an area we actually pull. If you're outside those, you get no sale badge rather than another city's deals — a Toronto shopper being shown a Winnipeg-only chain's price is worse than showing nothing.
None of this is a separate spreadsheet you maintain. It rides along inside the plan-shop-cook loop you're already using. See how the whole loop fits together →