Sitefold Design

Installation

Local development runs with no provider credentials. There is nothing secret to copy between machines.

Prerequisites

Two things, and neither is a credential:

  • nvm, so nvm use picks up the Node version in .nvmrc — the same one both machines and CI run.
  • git, authenticated. gh auth login is simplest: it handles HTTPS pushes with no SSH key to manage.

You do not need a Cloudflare login, a Resend account, or a database.

Setup

git clone https://github.com/measham/Sitefold.git
cd Sitefold
nvm use
npm install
cp .dev.vars.example .dev.vars
npm run dev

Open http://127.0.0.1:3000. That is the whole setup.

Two things happen for you: predev copies the Astro WASM compiler into public/, and SITEFOLD_DB_MIGRATION_MODE=auto means the local database creates and migrates itself on first start.

Looking at things

The dashboard is behind a login, so these routes exist to inspect surfaces directly without one:

/libraryThe component library — this documentation
/dev/builderThe builder shell
/dev/cmsThe CMS, on its green accent
/dev/settingsProject settings (?section=seo for a section)

Why no secrets are needed

  • AUTH_SECRET falls back to a development secret locally. Production refuses to start a session without a real one.
  • RESEND_API_KEY is optional. Without it, email falls back to a driver that logs the message — including the link — so signup, verification and password reset can be followed end to end with no Resend account.

Copy RESEND_API_KEY and SITEFOLD_EMAIL_FROM across only if you want that machine sending real email — and move them through a password manager, never through chat or email.

What isn't shared between machines

.sitefold-data/ — around 157MB, per-machine, not synced. It holds the local database, project documents and publish artifacts.

Your projects do not follow you. A project built on one machine does not exist on the other. That is inherent to local-first development rather than something git can fix — treat the machines as independent development environments.

If you rebuild a local database, reattach existing storage with npm run db:restore-projects -- --email you@example.com, with the dev server stopped. PGlite is not multi-process safe: opening its directory from a second process while next dev holds it can corrupt it unrecoverably.

Before you push

The same four checks CI runs:

npx tsc --noEmit
npm run lint
npm test
npm run design:baseline

Use design:baseline, not design:audit. The audit exits non-zero at its known raw-value baseline, so it always looks like a failure. The baseline script holds the zero-tolerance categories at zero and the raw-value debt at its budget — see Working with tokens.

Pushing to main deploys. There is normally no reason to run wrangler yourself.

If something breaks

Cannot find the middleware moduleThe dev server was started before src/middleware.ts existed. Restart it.
A new migration's table is missingSame shape — the dev server predates the migration. Restart it.
RuntimeError: Aborted() from PGliteThe data directory was opened by two processes. The pglite.broken-* directories are previous instances of this.
A token silently does nothingAn undefined custom property drops its whole declaration, with no error. This is the single most common trap here.