Skip to contact form
← BlogProcessJanuary 31, 2027 · 4 min read

Our pricing calculator won't sell you something broken

Check e-commerce without a backend and most quote tools just take your money. Ours won't let the selection be inconsistent in the first place. Try it below.

-commerce needs somewhere to store orders. A booking system needs somewhere to store bookings. Neither of those is optional — they're not features you could theoretically ship without a backend, they're features that are a backend with a nice interface on top. A pricing calculator that lets you check "E-commerce" without also accounting for the backend it structurally requires isn't being flexible, it's just wrong, and whoever sold it that way finds out at kickoff, not at checkout.

Checksomethingthatneedsabackend,andthebackendgetsaddedforyounotasanupsell,asacorrectiontokeeptheselectionactuallybuildable.

Try it

try checking e-commerce or booking without the backend

That checklist calls expandAddOnDependencies() imported directly from lib/pricing.ts — the exact function our real /start calculator runs on every selection change. It walks a small dependency map (ADD_ON_REQUIRES) and keeps expanding the selected set until nothing new gets pulled in — e-commerce and booking both silently require Custom Backend / API, and subscriptions requires that plus user accounts. Nothing about this is a growth trick to inflate the invoice; it's the calculator refusing to represent a combination that can't actually be built.

typescript

export const ADD_ON_REQUIRES: Partial<Record<AddOnKey, AddOnKey[]>> = { ecommerce: ['custom-backend'], booking: ['custom-backend'], subscriptions: ['custom-backend', 'user-accounts'], 'push-notifications': ['custom-backend'], 'admin-dashboard': ['custom-backend'], }; export function expandAddOnDependencies(selected: AddOnKey[]): AddOnKey[] { const result = new Set(selected); let grew = true; while (grew) { grew = false; for (const key of Array.from(result)) { for (const req of ADD_ON_REQUIRES[key] ?? []) { if (!result.has(req)) { result.add(req); grew = true; } } } } return Array.from(result); }

It also refuses to double-charge you

The reverse case matters just as much. A Web App's base price already assumes a backend and user accounts — that's what "an app people log into" means. If a client checked "Web App" and separately checked "Custom Backend / API," a naive calculator would just add both line items and charge twice for the same underlying thing. BASE_SERVICE_INCLUDES marks that add-on as already bundled for that base service — still shown as included in the summary, since the product genuinely has it, but priced at zero and locked, because unchecking it wouldn't actually remove a backend from a Web App.

Why bother, if most visitors would never notice

Most people configuring a quote don't know which add-ons quietly require a backend — that's exactly why this logic has to live in the tool instead of in a salesperson's head. The alternative isn't "nothing goes wrong," it's "something goes wrong quietly, later, when the mismatch surfaces mid-build instead of at the moment you picked the wrong combination." A calculator that can represent an impossible selection eventually will, for someone, and the honest fix is making the impossible selection unrepresentable in the first place.

Want this kind of thinking on your project?

This is how we work through real decisions. If you're weighing a build of your own, tell us about it — we reply within 24 hours.