Snagset

One-package quickstart (Vercel)

A deployed instance, on a free plan, in about five minutes. Everything here is in the repository npx create-snagset writes for you.

1. Scaffold and push

npx create-snagset my-review
cd my-review
git init && git add . && git commit -m "Snagset"

Push it to GitHub. Check .env is not in the commit — the scaffold's .gitignore covers it, and it holds your signing key.

2. Import it into Vercel

Add the project from your GitHub repository. Vercel finds vercel.json and api/index.js; there is no framework preset to choose and no build command to set.

3. Add a Postgres

From the Vercel marketplace — Neon and Supabase both work, and both have a free tier. Vercel sets DATABASE_URL for you.

Use the pooled connection string if you are offered a choice. Serverless functions open a connection per instance, and a pooler is what stops that exhausting the database's limit.

4. Set the signing key

Copy SNAGSET_SECRET_KEY from your local .env into the project's environment variables, and SNAGSET_BASE_URL to your deployment's URL.

The key is required here, unlike locally. Running on your own machine, the server generates one to .snagset/secret.key on first boot. A serverless filesystem is ephemeral, so each instance would invent a different key — a session minted by one would fail to verify on the next, and an encrypted credential written by one would be unreadable by all the others. The server refuses to start without it and says so.

5. Migrate on deploy, not on boot

Set the build command to:

npx snagset migrate

Migrations take an advisory lock. On a long-running server that happens once, at startup; on serverless there is no startup to hook, and migrating on a cold request would put every instance behind the one applying DDL — on somebody's first page load. So it is a deploy step.

6. Claim it

Open your deployment. The logs print a claim URL; open it, set a password.

Or claim it without a browser by setting the four bootstrap variables before the first deploy — see self-hosting.

What you get

vercel.json already schedules the job runner:

{ "crons": [{ "path": "/api/jobs/run", "schedule": "* * * * *" }] }

That is what expires review links, downgrades write mode after the grace window, reaps unbound attachments and sends queued notifications. Set CRON_SECRET in the environment — the route returns 503 until you do, rather than running unauthenticated.

Costs, honestly

Free tierWhen you outgrow it
VercelHobby, for non-commercial usePro, if you are billing clients
Neon / Supabase~0.5 GBA few euros a month
ScreenshotsAn S3-compatible bucket, cents per month

Vercel's Hobby plan forbids commercial use. If you are billing clients for this work, that is a Pro plan — or any Node host, since the same package runs with npm start.

Or anywhere else

Nothing here is Vercel-specific except vercel.json. Railway, Render, Fly and a plain VPS all take the same repository with npm start, and the compose file runs it with Postgres included.