Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone cf614aedcf4cdabfa9c45095
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
AGENTS.md
# Forms Forms is a free form and survey builder with unlimited responses, and a free alternative to Typeform, Google Forms, Jotform, SurveyMonkey, Formspree and Microsoft Forms. It is an OpenApp in the OpenApps free apps store (https://free-apps.openapps.xyz/), owned by the OpenApps team. ## What it promises - Free, with no limit on forms, questions or responses, no ads and no paid tier. Never add a cap, an upsell or tracking. - No sign-up for the person building a form or for the people filling it in. Every visitor is a guest account created in the browser. - Only a form's owners can read its responses or change it. Owners are the browser that made the form and anyone who opens its admin link. People filling in a form never see other responses. - Every form doubles as a website form endpoint: a plain HTML form can post to it with no script. - AI assistants can do everything a person can through the public API (`functions/api.ts`), documented in `public/llms.txt`. Keep that file true whenever the API changes. ## How it is built - `index.html` is the static landing page that search engines and AI crawlers read. Keep its copy, comparison table, FAQ and JSON-LD in sync with what the app does, and `public/index.md` (the same page as plain markdown) in sync with it. Competitor figures link to each company's own pricing page with the month they were checked; check them again before changing the date. - `src/` is the React app. `/` keeps the landing (and lists "Your forms" from localStorage); `/new` is the builder; `/f/<id>` is the public form; `/f/<id>/results` (summary), `/f/<id>/responses`, `/f/<id>/edit` and `/f/<id>/share` are the owner pages. - The public form reads the form from the public API (`GET /forms/<id>`) and sends the response there, so respondents never sign in and the page does not load the account library. The builder and owner pages load it on demand (`React.lazy` in `src/main.tsx`). Answers in the link (`?<label or id>=<answer>`) are filled in ahead, and a half-filled form is kept in sessionStorage. - `functions/lib/forms.ts` is shared by the app and the API: question types, form and answer checks, conditions (`showIf`: show a question only when an earlier choice, checkboxes, dropdown or yes or no answer matches; hidden questions are skipped), summaries (including the Net Promoter Score for the 0 to 10 `scale`) and CSV. Change validation there so both sides stay identical. - `functions/lib/config.ts` holds the app id, the site URL and the API base used in links. - `public/llms.txt` and `public/openapi.json` describe the API for assistants. Keep both true whenever the API changes. - `policy.json` holds the data rules: - `forms/<id>` is readable by anyone who joined it (`forms/<id>/joins/<userId>`, which needs only the id), and writable by owners. - `forms/<id>/owners/<userId>` is created by the creator in the same batch as the form, or by anyone who writes the matching admin key into `formclaims/<id>/c/<userId>` in the same batch. - `formkeys/<id>` holds the 24-character admin key. Only the API's public principal can read it, to check keys callers present. - `forms/<id>/responses/<responseId>` can be created by anyone who joined while the form is not closed, with `by` set to themselves; only owners can read or delete them; nobody can edit them. - The admin link carries the key in the URL fragment (`#k=`), which never reaches a server. The app moves it into localStorage and removes it from the address bar. - Live reads return at most 1,000 rows, so the results page reloads every page of responses when a form has more (`useResponses` in `src/Owner.tsx`); the API pages through them the same way. - The hosted pages cannot be framed by other websites (the platform's `frame-ancestors` header), so "put it on your website" means the HTML form snippet that posts to the endpoint, not an iframe. ## Working on it ```bash npm install npm run build # typecheck + build to dist/ ``` Forms is an OpenApp, so nobody deploys it directly: changes ship through previews and releases as your runtime instructions describe. Check a change by building a form with every question type and a condition, answering it on a phone from a second browser while the summary is open in a first, reading the results and CSV, posting an HTML form to the endpoint, and calling every API route with curl, including a wrong owner key. ## Voice Plain words, short sentences, no jargon, no em dashes. Say what happens, not how clever it is.
Change history
Quality pass: conditional questions, 0 to 10 scale, QR code, prefill links, results tabs, API docs
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync