Inspiration

Checkout is the last moment where a purchase is still a choice. After that, the money is gone. It is also the moment when every shopping site is built to hurry you: one more click, and the item is yours.

Most money tools look at what you already spent, in a budget app, after the fact. We wanted to help at the point of decision, and to do it without connecting a bank account or judging anyone's finances. Plenty of small purchases aren't bad, they just aren't worth it: a cheaper store brand sitting one aisle over, a tumbler you bought three weeks ago, a novelty plush you'll never use, a candy bar that is mostly added sugar. Those dollars add up, and a dollar saved today can compound for decades.

So we built Worth It, a Chrome extension that gives you one moment to think twice before you pay, and then shows what that money could become.

What it does

Worth It reviews your Walmart (and Amazon) cart at checkout. Nothing of ours appears on the cart page while you shop. When you click the retailer's checkout button and there's something worth a second look, that first click is held once and a short, full-screen presentation plays. It highlights at most three items, each with the retailer's own product thumbnail, a short verdict, and one piece of advice or a question. Everything else is grouped. A running savings meter tracks what you'd keep, and the presentation ends with one animated chart of what that saving could grow to if invested for 40 years (10% assumed return).

What it looks for:

  • Cheaper store brands, but only when product data supports the comparison.
  • Recent similar purchases. If you bought something like it recently, Worth It asks one question: is this a replacement, an extra, or a gift? Your answer changes the advice.
  • Novelty items with no practical use ("probably not worth it").
  • Food labels, read from the product's own Walmart page: added sugar, cured or processed meat, trans fat, non-sugar sweeteners, high sodium, synthetic dyes, and ultra-processed ingredients. Each has fixed, reviewed wording and a vetted source. A food with nothing flagged gets no comment.

WorthIt informs and suggests.

You can connect Gmail to import past receipts to get a sense of your shopping patterns.

How we built it

  • Chrome Manifest V3 extension built with WXT (Vite), TypeScript in strict mode, and React 19 for the checkout presentation, the options page, and the order-review screens. The animation is inline SVG and CSS, not a pre-rendered video.
  • Retailer adapters. A small RetailerAdapter interface reads cart rows from the page; Walmart came first and Amazon followed through its own adapter. Content scripts only read item rows on the cart page, never payment, address, or sign-in fields.
  • A deterministic assessment engine. Criteria, scores, savings, and grouped cart statistics are fixed, versioned, and computed in code. Product facts come from bundled, reviewed reference data (store-brand pairings, label facts) plus each cart item's own product page. An LLM, if you turn it on, may only phrase an already-verified summary. It cannot score, calculate, add claims, or alter evidence, and any output that fails validation falls back to reviewed templates.
  • On-device everything. Purchase history lives in IndexedDB (via idb), preferences in chrome.storage.local. There is no backend, no bank connection, and no analytics. Gmail goes through Chrome's identity API with the read-only scope, and receipts are parsed locally.
  • On-device similarity matching (cosine similarity over product-name words) to catch repeat purchases that a keyword list would miss.
  • Tested end to end. Hundreds of Vitest unit and integration tests, plus Playwright browser tests that load the real extension against fixture pages transcribed from the live Walmart cart. Gmail and OpenAI are tested through stubbed endpoints, and we wrote a script that sends labeled synthetic receipt emails through the same Gmail import path.
  • Built issue by issue. We worked from a PRD, a technical spec, and an issue-linked implementation plan, with every change landing as a reviewed PR.

Challenges we ran into

  • Reading a live retail page we don't control. Walmart's cart markup doesn't match any tidy fixture. Our first reader fell back to link scanning and would have counted the "Don't forget your usuals" recommendation carousel as cart items. Then Walmart turned out to share one product-tile container across several items (a cheese and a milk in the same tile), so we had to read each row independently. We now transcribe sanitized live markup into fixtures, and when a line can't be read, Worth It says so instead of guessing.
  • Sale prices that looked like errors. A Rollback item announces its price to screen readers as one sentence: "Current price $3.97, Was $4.43, You save $0.46." Our extractor threw away anything mentioning "Was", then saw two leftover amounts and gave up, which blanked the item's price and broke the cart total. We rebuilt price reading to interpret each dollar amount using the words and markup around it, and it still refuses to choose between two unlabeled amounts.
  • A bug that only showed up on older Chrome. The cart review worked in development and silently failed on some Chrome versions: the panel mounted but never received a review. The cause was a Promise-returning message listener, which WXT stopped polyfilling in v0.20. We switched to sendResponse with a synchronous return true, tested the real background listener against callback semantics, and added privacy-safe diagnostics (no product names, prices, or raw errors) so a missing panel can be debugged on someone else's machine.
  • Holding a click without being a nuisance, or a hijacker. The checkout hold has to catch the shopper's first real click and nothing else. It must ignore scripted clicks, never hold twice, never hold when there's nothing to show, and re-arm correctly after a reload. It also can't wait for slow product pages: our first version waited about four seconds on a seven-item cart, so an early click slipped through. We now review the cart immediately from the cart page, re-review once product pages are read, and never swap results under a shopper who is already reading.
  • Staying polite to Walmart. Reading product labels means fetching pages, so we limited it to items already in the cart, same-origin, a few at a time, cached on-device for a day, retried on transient errors, and stopped at the first bot check ("Robot or human?"). In that case the item is reported as unknown.
  • Health claims have to be right. We deliberately limited food guidance to a short list of approved concerns, each with fixed wording and one vetted source. There are no Daily Value percentages, no diagnoses, and no claims that one serving causes disease. "Ultra-processed" turned out to be the hardest call: identifying it from an ingredient list is deliberately broad, so the note says exactly what its source study does and doesn't show.
  • Restraint was the hardest design problem. Our early versions were analysis tools, with scores and tables. We rewrote the experience as an advisor that makes you think twice: three highlights, plain words, one chart. The full breakdown moved behind a button. We also decided the presentation can't be skipped, so the pause actually happens, with pause, replay, captions, and a static view for reduced motion.
  • Setup we couldn't fake. Gmail OAuth hits "invalid client ID" errors that Chrome reports confusingly, so we made Worth It show the extension's ID and Chrome's own message instead of a generic "not configured."

Accomplishments that we're proud of

  • A real, usable extension, not a demo. There's no demo mode. Install it, open a Walmart cart, click Checkout, and it works on live pages.
  • Trustworthy by construction. Every number comes from code, every health note from fixed reviewed text with a source, and every uncertainty is reported rather than guessed. The AI can polish wording but can't change a finding.
  • Privacy as a feature. No bank accounts, no backend, read-only Gmail with a human review step, no raw email retention, and a minimal permission list (no tabs, history, cookies, or all-sites access).
  • It never touches your cart. The shopper stays in control. Worth It adds a pause and never makes the decision.
  • A thorough test suite. 300+ unit and integration tests and a Playwright suite that drives the real extension, including failure paths: declined Gmail consent, unreadable cart lines, bot checks, invalid LLM output, and carts with nothing to flag.
  • A presentation that holds up. A full-screen animated recap with thumbnails, a savings meter, and a growth chart, with captions, pause and replay, and a reduced-motion version.
  • Two retailers, one engine. Walmart end to end, with Amazon added through the same adapter interface.

What we learned

  • The checkout moment is a design problem as much as a technical one. Interrupting a shopper is expensive. The product only works if it speaks rarely, briefly, and credibly, so most of our decisions were about what not to show.
  • Deterministic first, language model second. Keeping the model out of scoring, math, and evidence made the product easier to test and to trust. An LLM that only rephrases verified facts can't hallucinate a saving.
  • Real pages beat assumptions. Sale prices, grouped tiles, carousels, and bot checks only showed up on the live site, so fixtures transcribed from real markup and honest "couldn't read this" paths paid for themselves.
  • Chrome extension quirks are real. Message-channel semantics, stale content scripts after a rebuild ("Extension context invalidated"), and OAuth client setup each cost us hours, and each is now documented.
  • Writing the spec first kept a fast project coherent. A PRD, tech spec, and issue-linked plan let us make product decisions once, in writing, and then build against them.

What's next for WorthIt

  • Run the live paths end to end. The Gmail import, OpenAI wording, and signed-in order-page recording are built and tested against stubs, but need to be verified against real accounts.
  • Amazon depth. The Amazon adapter reads carts today, but Amazon has no product-page reader or reviewed reference data yet. Adding both would bring label checks and store-brand comparisons to Amazon.
  • More reviewed products and store brands, and better matching for functionally equivalent items.
  • Smarter repeat detection. Better handling of replacements and upgrades, and learning from the shopper's answers over time.
  • Optional public release. That means a server-side proxy so the OpenAI key never lives in the browser, Chrome Web Store listing assets, and Google's OAuth verification for the Gmail scope.
  • More retailers, and reflection. Save-for-later, price-drop monitoring on items you decided to wait on, and ways to measure whether Worth It actually reduces purchase regret.

Built With

Share this project:

Updates

Submission history