A form builder that works like a document: you type a page and typing a question makes a field. It leans on calculations, payments and long-form layouts rather than short surveys.
Build me a form that reads like a page, replacing Paperform: I write a document, the questions are part of the prose, and the total adds itself up. STACK - Node 20+ with Fastify, server-rendered HTML with a little vanilla JS - SQLite through better-sqlite3, WAL mode - One payment provider, hosted checkout - Caddy in front THE ONE IDEA - The form is a document. You write a page of prose and a question is inserted inline, in the middle of a sentence if that is where it belongs - 'We will deliver to [address] on [date] for [quantity] people' is one sentence with three fields in it, and it reads better than four labelled boxes - So the editor is a writing surface, not a block assembler, and the rendered form keeps the prose around the fields - Everything below serves that. If a feature would turn the page back into a stack of labelled boxes, leave it out THE DATA MODEL - forms: id, slug, name, version, content_json, theme_json, status, published_at - form_versions: id, form_id, version, content_json, published_at — a submission records the version it was filled against - fields: within the content — key, kind, label, help, required, validation_json, options_json, calculation, price_json - submissions: id, form_id, form_version, token, status, started_at, submitted_at, total_cents, currency, payment_id, ip_hash - answers: id, submission_id, field_key, value_text, value_num, value_json - coupons: id, code, kind, value, max_uses, used_count, expires_at, applies_to_json - payments: id, submission_id, provider_ref, amount_cents, currency, status, paid_at - The content is one document tree with text nodes and field nodes. That representation is the whole design and everything else derives from it WRITING THE FORM - A rich text editor where typing a marker inserts a field inline, configured in a panel beside it - Headings, paragraphs, lists, images, dividers and page breaks, because it is a document - A live preview at phone and desktop width, showing the real thing - Themes: font, colours, background, spacing. It should look like a page from the site it belongs to, not like a form vendor's product FIELD KINDS - Text, long text, number, email, phone, date, time, dropdown, radio, checkbox, scale, rating, address, file upload, signature, hidden - Price fields: a fixed amount, a quantity multiplied by a unit price, an option list with prices, or a value computed from other answers - Each kind has a parser, a validator, an inline rendering that fits inside a sentence, and a CSV form CALCULATIONS, WHICH IS WHY THIS PRODUCT IS CHOSEN - A small expression language over field keys: arithmetic, conditionals, rounding, min and max, and sums over repeated groups - Parsed into an AST with a dependency graph, so a cycle is rejected at save time rather than found by somebody filling the form - The running total updates as they type, visible, itemised — a total that appears only at the end loses people - Tax computed as a rule with its rate and whether prices include it, stated on the page - Coupons applied against the itemised total with the rule visible - The server recomputes every calculation from the answers before charging. The browser's total is a display and is never trusted. This is the classic way a payment form is abused, and it is one function to get right CONDITIONS - Show or hide a field, a paragraph or a whole page depending on earlier answers - An explicit expression tree, never evaluated code, with one evaluator shared by the server and the browser so what is shown and what is accepted cannot disagree - Validated on save: an unknown reference or an unreachable page is an error before publishing FILLING IT IN - Page breaks make it multi-step; each page is a real POST, so back and forward work and a refresh loses nothing - Progress saved and resumable by a token emailed to the person filling it - Errors on the field with the value kept - Works with JavaScript disabled apart from the live total, which is enhancement PAYMENT - Hosted checkout; no card data reaches this application - The amount comes from the server's own recomputation, always - Webhook with signature verification and idempotency by event id; the submission is marked paid only from the webhook - A failed payment keeps the submission rather than discarding it AFTER - Notifications to the owner and an autoresponder with a copy of the answers and the itemised total - A success page that can be written like any other page, with the answers available in it - Export CSV and JSON, complete, with totals and payment references OPERATIONS - .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, SESSION_SECRET, SMTP_URL, PROVIDER_KEY, PROVIDER_WEBHOOK_SECRET, HASH_SALT - Migrations on boot, each once - Nightly backup off the machine, restore script - Health endpoint WHAT MATTERS MOST The inline field rendering and server-side recomputation of the total. Build the document tree with fields inside sentences first — that is the product — and never charge an amount that came from a browser. Give me the repository, migrations, .env.example, a seed order form with prices, a coupon and a calculation, and a README with deploy steps behind Caddy.
What you lose
- A document-style editor where the form is written like a page rather than assembled from blocks
- Calculations and price fields with a live total, including tax and coupon handling
- Stripe checkout inside the form, with the payment tied to the submission
- Scheduling fields that read a calendar and hold a slot while the form is being filled
- Hosted pages with themes that look designed without design work
If you would rather not build
- Fillout — paid, closest builder, generous free tier
- Typeform — paid, one question per screen instead of a document
What it costs
read from their page 15 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $29/mo | — | 15 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
Formbricks
$0Survey and form platform with logic, targeting and self-hosting.
formbricks/formbricksfree · open source
OhMyForm
$0Self-hosted form builder with logic and exports, a lighter option to run.
ohmyform/ohmyformfree · open source
Why this verdict
our own opinion · changed only by a person
76/100
Verdict yes at 76: the interesting half is the price expression evaluated twice, and the prompt is explicit that only the server total may reach Stripe. The editor experience — writing a page and getting a form — is the part a build will not match.
History
tracked since 9 Aug 2026 · nothing is ever overwritten
Questions about Paperform
answered from the record above
Is Paperform free?
No — the plan we track is $29 a month. Essentials at $29/month billed monthly, around $24 annually; limits are on forms and monthly submissions.
Can you replace Paperform by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 76 out of 100, build time one session. Read what you lose before you decide.
How much does Paperform cost?
$29 a month on Essentials — $348 a year. Recorded 9 Aug 2026.
What do you lose by replacing Paperform?
A document-style editor where the form is written like a page rather than assembled from blocks; Calculations and price fields with a live total, including tax and coupon handling; Stripe checkout inside the form, with the payment tied to the submission; Scheduling fields that read a calendar and hold a slot while the form is being filled; Hosted pages with themes that look designed without design work. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Paperform?
Yes: Formbricks, OhMyForm. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

