Scaffold a Strata Sync App
Generates a runnable local-first app: a Next.js client and a standalone Fastify API with PostgreSQL, converging over a server-sequenced log.
- IS: creating a new Strata Sync project from nothing, or adding the full client and server sync layer to an existing Next.js app.
- IS NOT: changing an app that already syncs (use the
stratasyncskill), general Next.js scaffolding (usescaffold-nextjs), or deployment.
Strata Sync is a clean-room implementation of the architecture Linear published; it contains no Linear code. The reverse-engineering notes are the reference for the concepts named here.
Reference files
| File | Purpose |
|---|---|
references/client-setup.md |
Next.js client: tsconfig, next.config, deps, model, client factory, providers, page |
references/server-setup.md |
Fastify server: docker-compose, drizzle schema, server entry, config |
references/model-patterns.md |
Adding models, instance methods (.save/.delete/.archive), relations, load strategies, server config |
Variables
| Variable | Description | Default |
|---|---|---|
{{PROJECT_NAME}} |
Project directory and database name | my-stratasync-app |
{{MODEL_NAME}} |
Primary model name (PascalCase) | Todo |
{{MODEL_NAME_LOWER}} |
Model name (lowercase) | todo |
{{MODEL_TABLE}} |
Database table name (plural lowercase) | todos |
{{API_PORT}} |
Server port | 3001 |
{{WEB_PORT}} |
Client dev port | 3002 |
Workflow
Phase 1: Gather info
- Ask for project name (default:
my-stratasync-app) - Ask for primary model name (default:
Todo) - Ask for model fields beyond defaults (
id,groupId,createdAt) - If user says "just defaults" or gives no specifics, use Todo with
title: stringandcompleted: boolean - Derive
MODEL_NAME_LOWERandMODEL_TABLEfromMODEL_NAME
Phase 2: Scaffold Next.js client
- Detect if inside an existing Next.js project (check for
next.config.*) - If no existing project: run
npx create-next-app@latest {{PROJECT_NAME}} --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"with--use-npm - Install client dependencies per
references/client-setup.md§ Dependencies - Merge tsconfig changes per
references/client-setup.md§ tsconfig.experimentalDecorators: trueis CRITICAL. - Write
next.config.tsperreferences/client-setup.md§ next.config.transpilePackagesis CRITICAL.
Phase 3: Scaffold server
- Create
server/directory alongside the client - Write all server files per
references/server-setup.md:server/package.jsonserver/tsconfig.jsonserver/docker-compose.ymlserver/.env.exampleserver/.env(copy from.env.example)server/drizzle.config.tsserver/src/db/schema.tsserver/src/config.tsserver/src/server.ts
- Run
cd server && npm install
Phase 4: Scaffold client sync layer
Write all client sync files per references/client-setup.md:
-
src/lib/sync/models/{{MODEL_NAME_LOWER}}.ts: Model class with decorators -
src/lib/sync/models.ts: Barrel with side-effect import (CRITICAL: decorator registration) -
src/lib/sync/config.ts: API URL, dev tokens -
src/lib/sync/create-client.ts: Client factory (singleton) -
src/app/providers.tsx:NextSyncProviderwrapper -
src/app/layout.tsx: Wrap children with<Providers>
Phase 5: Scaffold example page
- Write
src/app/page.tsxperreferences/client-setup.md§ Example page - Includes: create form, toggle, delete, sync status display
- Uses
useQuery,useSyncClient,useConnectionState,observer, and instance.save()/.delete()methods - All components marked
"use client"
Phase 6: Start and verify
-
cd server && docker compose up -d: Start PostgreSQL -
cd server && npm run db:push: Create database tables -
cd server && npm run dev: Start API server (port {{API_PORT}}) - In a new terminal:
npm run dev: Start Next.js (port {{WEB_PORT}}) - Verify: open
http://localhost:{{WEB_PORT}}, create a todo, confirm it persists across refresh - Verify: open a second tab, confirm real-time sync via WebSocket
Anti-patterns
- Never omit
experimentalDecorators: truefrom tsconfig. Decorators fail silently. - Never omit
transpilePackagesfrom next.config. ESM imports break at runtime. - Never forget side-effect model imports in the barrel file. Schema will be empty, no data syncs.
- Never install
@stratasync/serverin the client app. It is server-only. - Never import
@stratasync/nextdirectly in client components. Use@stratasync/next/client. - Never omit
"use client"on components that use hooks - Never use
React.forwardRef. React 19+ passes ref as prop.
Skill handoffs
| When | Hand off to |
|---|---|
| User wants to add more models | Refer to references/model-patterns.md |
| User wants authentication | Beyond scaffold scope. Point to StrataSync server auth docs. |
| User wants deployment | Beyond scaffold scope. Standard Next.js + Node.js deployment. |
| User wants collaborative text editing | Point to @stratasync/y-doc package |