Small-business software, minus the plumbing.
Login, people, files, notes, todos, reminders, backups and an assistant are already built. You write the app that is actually about the business. A client gets a private fork that pulls platform updates and never edits core.
Fork it. Bake it. Release it. A springform is the pan a cheesecake comes out of whole. The form stays on the foundation; what you made lifts off it.
What you get out of the box
Every record in every app gets the same core: a timeline, attachments, custom fields, saved views, reminders and notifications. Apps add the parts that are about the business.
Login that is not a project
Password plus an authenticator app, or sign in with Google. Invite-only. Admins and members, nothing more.
One directory of people
People and organizations, linked with a role, shared by every app. Duplicate finding and merge built in.
Timelines and files on any record
Notes, comments, @-mentions and field history on everything. Attachments live on the volume, deduplicated by hash.
Fields, views and reports
Custom fields of eight types, saved views per screen, and CSV reports an app registers in one line.
Reminders and notifications
In-app, with web push. A reminder re-checks that you may still see the record before it fires.
Backups you can restore
A nightly snapshot plus the files and the encryption key, with a restore script and a restore test in CI.
Whisk, the assistant
Knows the installed apps and their records. Proposes a write before making it. Runs with zero AI keys; chat waits for one.
MCP, both ways
Each user can mint a link that gives Claude the same tools with the same permissions. Admins can connect Whisk to other MCP servers.
Jobs, Sheets, Guide, Requests
A scheduler with a Jobs page, connected Google Sheets, an in-app guide built from the docs, and a request board that files GitHub issues.
CRM
Pipeline, deals, activities, scoring, dashboards. Ported from a CRM that runs a real company.
Todos
Private by default, team todos anyone can pick up, attached to any record. Today, review, recurring.
The app about the business
A folder with an app.json. Routes, screens, migrations, tools, jobs and docs are discovered at boot and land on the launcher.
How it's put together
Deliberately small. If you can run a Docker container, you can run this.
FastAPI and Pydantic behind
Python 3.12. One process, one writer, SQLite with WAL and FTS5. No queue, no cache server, no Postgres.
React and TypeScript in front
Vite, Tailwind, React Router. Types are generated from the API, and CI fails when they drift.
Apps are folders
Tables are prefixed with the app's slug. Apps talk to each other only through published functions. A contract test enforces both.
Tested like it matters
Every pull request runs the backend, frontend, image and browser suites, plus a secret scan. Forks run the same workflow.
Fork it. Bake it. Release it.
A client's software is a private repository that starts from a tagged release. Core stays byte-identical to that tag; the apps are theirs.
Fork it
One script makes the private repo, pins the release, seeds labels and waits for the first green CI run.
scripts/new-fork.sh acme --org acme-co
Bake it
Scaffold an app, then build. CI's Fork scope job fails any change outside the app folders, so core never drifts.
scripts/new-app.sh invoices "Invoices"
Release it
Pull the next platform release as a pull request. Tag the fork and it builds its own image, apps included.
scripts/update-from-upstream.sh v0.2.0 git tag v0.2.0-acme.1
Why not a GitHub button fork? A fork of a public repo cannot be private. This is a clone with a fetch-only upstream, which can.
Run it
On first boot the log prints a one-time setup token for creating the first admin. Nothing is created by whoever visits first.
On your laptop
The published image, data in a named volume.
docker run -p 8000:8000 \ -v springform-data:/data \ ghcr.io/wwilson1017/springform:latest
On a server
A fresh Ubuntu 24.04 machine whose DNS name already points at it. Docker, Caddy with automatic HTTPS, a firewall, security updates and an off-site backup cron.
git clone \ https://github.com/wwilson1017/springform.git sudo DOMAIN=app.example.com \ springform/deploy/setup.sh
On Railway
The repo carries a railway.json: Dockerfile build, health check on /up, a volume at /data.
Set SECRET_KEY, PUBLIC_URL, TRUST_PROXY=1, and attach a volume.
Deploys are stop-before-start. SQLite has one writer, and the app holds a lock on the volume so a second copy refuses to start. Expect a few seconds of downtime per deploy, and never more than one worker.
Why this exists
Every time a small business gets its own software, the same first month gets rebuilt: login, users, a contacts list, files, notes on records, to-dos, a scheduler, backups, a helper, and a way to file the next change. Springform is that month, done once, with the extension points a real client needed and did not have.
It is built in the open by Will Wilson, who runs a cheesecake bakery in Tennessee and writes the software that runs it. The CRM and the todo app are ports of tools that already run that business.
What it is not: a no-code builder, a multi-tenant SaaS, or a framework that hides the database. It is a repository you read, a container you run, and a folder you add.
Where it stands: first releases in October 2026, first production install in November. Sharp edges remain. File what you hit.