### Local Development Setup with bun
Source: https://zero.rocicorp.dev/docs/install
Starts the `zero-cache-dev` tool locally using bun. Requires `ZERO_QUERY_URL` and `ZERO_MUTATE_URL` environment variables to be configured.
```bash
ZERO_QUERY_URL="http://localhost:3000/api/query" \
ZERO_MUTATE_URL="http://localhost:3000/api/mutate" \
bunx zero-cache-dev
```
--------------------------------
### TanStack Start ZeroProvider Setup
Source: https://zero.rocicorp.dev/docs/install
Integrates ZeroProvider into the root document for TanStack Start applications. Ensure the schema is imported correctly.
```tsx
// src/routes/__root.tsx
import {ZeroProvider} from '@rocicorp/zero/react'
import type {ZeroOptions} from '@rocicorp/zero'
import {
HeadContent,
Scripts,
createRootRoute
} from '@tanstack/react-router'
import type {ReactNode} from 'react'
import {schema} from '../zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema
}
export const Route = createRootRoute({
shellComponent: RootDocument
})
function RootDocument({children}: {children: ReactNode}) {
return (
{children}
)
}
```
--------------------------------
### Local Development Setup with pnpm
Source: https://zero.rocicorp.dev/docs/install
Starts the `zero-cache-dev` tool locally using pnpm. Requires `ZERO_QUERY_URL` and `ZERO_MUTATE_URL` environment variables to be configured.
```bash
ZERO_QUERY_URL="http://localhost:3000/api/query" \
ZERO_MUTATE_URL="http://localhost:3000/api/mutate" \
pnpm exec zero-cache-dev
```
--------------------------------
### Local Development Setup with npm
Source: https://zero.rocicorp.dev/docs/install
Starts the `zero-cache-dev` tool locally using npm. Requires `ZERO_QUERY_URL` and `ZERO_MUTATE_URL` environment variables to be configured.
```bash
ZERO_QUERY_URL="http://localhost:3000/api/query" \
ZERO_MUTATE_URL="http://localhost:3000/api/mutate" \
npx zero-cache-dev
```
--------------------------------
### Local Development Setup with yarn
Source: https://zero.rocicorp.dev/docs/install
Starts the `zero-cache-dev` tool locally using yarn. Requires `ZERO_QUERY_URL` and `ZERO_MUTATE_URL` environment variables to be configured.
```bash
ZERO_QUERY_URL="http://localhost:3000/api/query" \
ZERO_MUTATE_URL="http://localhost:3000/api/mutate" \
yarn exec zero-cache-dev
```
--------------------------------
### Start Development Server (npm)
Source: https://zero.rocicorp.dev/docs/tutorial
Starts the development server using npm. This command is essential for `zero-cache` to connect to your query endpoint.
```bash
npm run dev
```
--------------------------------
### Start Development Server (bun)
Source: https://zero.rocicorp.dev/docs/tutorial
Starts the development server using bun. This allows `zero-cache` to communicate with your query endpoint.
```bash
bun run dev
```
--------------------------------
### Download Zero Schema
Source: https://zero.rocicorp.dev/docs/tutorial
Download the example music-app schema for Zero. This is a quickstart method; in real applications, generate the schema from your Drizzle or Prisma schema.
```bash
mkdir -p src/zero
curl https://raw.githubusercontent.com/rocicorp/zero-music/1-install/packages/zero/src/schema.ts \
-o src/zero/schema.ts
```
--------------------------------
### postgres.js DB Provider Setup
Source: https://zero.rocicorp.dev/docs/install
Configure the postgres.js client with the Zero adapter. Ensure your database client is installed and the ZERO_UPSTREAM_DB environment variable is set.
```typescript
// src/zero/db-provider.ts
import {zeroPostgresJS} from '@rocicorp/zero/server/adapters/postgresjs'
import postgres from 'postgres'
import {schema} from './schema'
const connectionString = process.env.ZERO_UPSTREAM_DB
if (!connectionString) {
throw new Error('ZERO_UPSTREAM_DB is not set')
}
const sql = postgres(connectionString)
export const dbProvider = zeroPostgresJS(schema, sql)
// Register global types for mutators on the server
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Start Zero-Cache Development Server with npm
Source: https://zero.rocicorp.dev/docs/tutorial
Launches the zero-cache development server using npm.
```bash
npx zero-cache-dev
```
--------------------------------
### Start Zero-Cache Development Server with bun
Source: https://zero.rocicorp.dev/docs/tutorial
Launches the zero-cache development server using bun.
```bash
bunx zero-cache-dev
```
--------------------------------
### Start Development Server (pnpm)
Source: https://zero.rocicorp.dev/docs/tutorial
Starts the development server using pnpm. Ensure your app server is running so `zero-cache` can reach the query endpoint.
```bash
pnpm dev
```
--------------------------------
### node-postgres DB Provider Setup
Source: https://zero.rocicorp.dev/docs/install
Set up the node-postgres client with the Zero adapter. Confirm that your database client is installed and the ZERO_UPSTREAM_DB environment variable is configured.
```typescript
// src/zero/db-provider.ts
import {zeroNodePg} from '@rocicorp/zero/server/adapters/pg'
import {Pool} from 'pg'
import {schema} from './schema'
const connectionString = process.env.ZERO_UPSTREAM_DB
if (!connectionString) {
throw new Error('ZERO_UPSTREAM_DB is not set')
}
const pool = new Pool({
connectionString
})
export const dbProvider = zeroNodePg(schema, pool)
// Register global types for mutators on the server
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Solid Start API Route Handler with Cookie Auth
Source: https://zero.rocicorp.dev/docs/auth
Example of handling POST requests in a Solid Start API route to authenticate using cookies.
```typescript
// src/routes/api/zero/query.ts
import type {APIEvent} from '@solidjs/start/server'
export async function POST(event: APIEvent) {
const session = await authenticate(
event.request.headers.get('Cookie')
)
// ... handle query ...
}
```
--------------------------------
### Install Zero 0.7
Source: https://zero.rocicorp.dev/docs/release-notes/0.7
Install the Zero 0.7 package using npm.
```bash
npm install @rocicorp/zero@0.7
```
--------------------------------
### Install Zero and Dependencies with pnpm
Source: https://zero.rocicorp.dev/docs/tutorial
Installs Zero, Zod, and pg using pnpm, including necessary steps to allow native package builds.
```bash
pnpm add @rocicorp/zero zod pg
pnpm add -D @types/pg
# Note: pnpm disables postinstall scripts by default for security.
# Create or update pnpm-workspace.yaml to allow the native package build:
# https://pnpm.io/settings#allowbuilds
# allowBuilds:
# '@rocicorp/zero-sqlite3': true
pnpm rebuild @rocicorp/zero-sqlite3
```
--------------------------------
### Install and Generate Drizzle Zero with bun
Source: https://zero.rocicorp.dev/docs/schema.md
Install the drizzle-zero package and run the generate command using bun.
```bash
bun add -D drizzle-zero
bunx drizzle-zero generate
```
--------------------------------
### Install Zero and Dependencies with bun
Source: https://zero.rocicorp.dev/docs/tutorial
Installs Zero, Zod, and pg using bun, and configures trusted dependencies for native package builds.
```bash
bun add @rocicorp/zero zod pg
bun add -d @types/pg
# Note: Bun disables postinstall scripts by default for security.
# Either approve the build:
bun pm trust @rocicorp/zero-sqlite3
# Or add to package.json, then rebuild the native packages:
# "trustedDependencies": ["@rocicorp/zero-sqlite3"]
```
--------------------------------
### Start Zero-Cache Development Server with pnpm
Source: https://zero.rocicorp.dev/docs/tutorial
Launches the zero-cache development server using pnpm.
```bash
pnpm exec zero-cache-dev
```
--------------------------------
### Install and Generate Prisma Zero with bun
Source: https://zero.rocicorp.dev/docs/schema.md
Install the prisma-zero package and run the prisma generate command using bun. Remember to add the generator to your prisma schema.
```bash
bun add -D prisma-zero
# Add this to your prisma schema:
# generator zero {
# provider = "prisma-zero"
# }
bunx prisma generate
```
--------------------------------
### Install Zero and Zod with npm
Source: https://zero.rocicorp.dev/docs/install
Installs the Zero package and Zod validator using npm. Zod is used as an example validator; any Standard Schema-compatible validator will work.
```bash
npm install @rocicorp/zero zod
```
--------------------------------
### Install Zero and Dependencies with npm
Source: https://zero.rocicorp.dev/docs/tutorial
Installs the Zero package, Zod for validation, and pg for Postgres interaction, along with TypeScript types for pg.
```bash
npm install @rocicorp/zero zod pg
npm install -D @types/pg
```
--------------------------------
### Prisma DB Provider Setup
Source: https://zero.rocicorp.dev/docs/install
Configure the Prisma ORM with the Postgres adapter for Zero. Ensure your database client is installed and the ZERO_UPSTREAM_DB environment variable is set.
```typescript
// src/zero/db-provider.ts
import {PrismaPg} from '@prisma/adapter-pg'
import {PrismaClient} from '@prisma/client'
import {zeroPrisma} from '@rocicorp/zero/server/adapters/prisma'
import {schema} from './schema'
const connectionString = process.env.ZERO_UPSTREAM_DB
if (!connectionString) {
throw new Error('ZERO_UPSTREAM_DB is not set')
}
const prisma = new PrismaClient({
adapter: new PrismaPg({
connectionString
})
})
export const dbProvider = zeroPrisma(schema, prisma)
// Register global types for mutators on the server
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Paginate Query Results in ZQL
Source: https://zero.rocicorp.dev/docs/zql
Implement pagination using `start()` to specify the starting row for results. By default, `start()` is exclusive. An inclusive option is available.
```typescript
let start: IssueRow | undefined
while (true) {
let q = zql.issue
.orderBy('created', 'desc')
.limit(100)
if (start) {
q = q.start(start)
}
const batch = await q.run()
console.log('got batch', batch)
if (batch.length < 100) {
break
}
start = batch[batch.length - 1]
}
```
```typescript
zql.issue.start(row, {inclusive: true})
```
--------------------------------
### Install and Generate Drizzle Zero with yarn
Source: https://zero.rocicorp.dev/docs/schema.md
Install the drizzle-zero package and run the generate command using yarn.
```bash
yarn add -D drizzle-zero
yarn exec drizzle-zero generate
```
--------------------------------
### Install Zero 1.2
Source: https://zero.rocicorp.dev/docs/release-notes/1.2
Install the Zero 1.2 version using npm. This command ensures you have the latest stable release for your project.
```bash
npm install @rocicorp/zero@1.2
```
--------------------------------
### Kysely DB Provider Setup
Source: https://zero.rocicorp.dev/docs/install
Set up the Kysely ORM with the Postgres adapter for Zero. Verify that your database client is installed and the ZERO_UPSTREAM_DB environment variable is configured.
```typescript
// src/zero/db-provider.ts
import {Kysely, PostgresDialect} from 'kysely'
import {zeroKysely} from '@rocicorp/zero/server/adapters/kysely'
import {Pool} from 'pg'
import {schema} from './schema'
import type {Database} from '../kysely/database'
const connectionString = process.env.ZERO_UPSTREAM_DB
if (!connectionString) {
throw new Error('ZERO_UPSTREAM_DB is not set')
}
const kysely = new Kysely({
dialect: new PostgresDialect({
pool: new Pool({
connectionString
})
})
})
export const dbProvider = zeroKysely(schema, kysely)
// Register global types for mutators on the server
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Install and Generate Drizzle Zero
Source: https://zero.rocicorp.dev/docs/schema.md
Install the drizzle-zero package and run the generate command using npm.
```bash
npm install -D drizzle-zero
npx drizzle-zero generate
```
--------------------------------
### Install and Generate Prisma Zero
Source: https://zero.rocicorp.dev/docs/schema.md
Install the prisma-zero package and run the prisma generate command using npm. Remember to add the generator to your prisma schema.
```bash
npm install -D prisma-zero
# Add this to your prisma schema:
# generator zero {
# provider = "prisma-zero"
# }
npx prisma generate
```
--------------------------------
### Install and Generate Drizzle Zero with pnpm
Source: https://zero.rocicorp.dev/docs/schema.md
Install the drizzle-zero package and run the generate command using pnpm.
```bash
pnpm add -D drizzle-zero
pnpm exec drizzle-zero generate
```
--------------------------------
### TanStack Start REST API for Zero Mutators
Source: https://zero.rocicorp.dev/docs/rest
This example demonstrates how to create a REST API endpoint using TanStack Start that maps incoming POST requests to Zero mutator functions. It handles mutator name parsing, argument retrieval, and executes the mutator within a database transaction. Ensure mutators are correctly imported and the database provider is configured.
```typescript
// app/routes/api/mutators/$.ts
import {createServerFileRoute} from '@tanstack/react-start/server'
import {mustGetMutator} from '@rocicorp/zero'
import {mutators} from 'zero/mutators'
export const ServerRoute = createServerFileRoute(
'/api/mutators/$'
).methods({
POST: async ({params, request}) => {
const name = params._splat?.split('/').join('.')
if (!name) {
return Response.json(
{error: 'Mutator name required'},
{status: 400}
)
}
const args = await request.json()
const mutator = mustGetMutator(mutators, name)
await dbProvider.transaction(async tx => {
await mutator.fn({
tx,
args
})
})
return Response.json({ok: true})
}
})
```
--------------------------------
### Solid Start API Route for Mutations
Source: https://zero.rocicorp.dev/docs/mutators
Implement a Solid Start API route to handle mutation requests. This snippet shows how to use `handleMutateRequest` within the Solid Start framework's server-side request handling.
```typescript
// src/routes/api/zero/mutate.ts
import type {APIEvent} from '@solidjs/start/server'
import {handleMutateRequest} from '@rocicorp/zero/server'
import {mustGetMutator} from '@rocicorp/zero'
import {mutators} from 'mutators.ts'
import {dbProvider} from 'db-provider.ts'
export async function POST(event: APIEvent) {
const result = await handleMutateRequest({
dbProvider,
handler: transact =>
transact((tx, name, args) => {
const mutator = mustGetMutator(mutators, name)
return mutator.fn({args, tx})
}),
request: event.request,
userID: null
})
return Response.json(result)
}
```
--------------------------------
### Install and Generate Prisma Zero with pnpm
Source: https://zero.rocicorp.dev/docs/schema.md
Install the prisma-zero package and run the prisma generate command using pnpm. Remember to add the generator to your prisma schema.
```bash
pnpm add -D prisma-zero
# Add this to your prisma schema:
# generator zero {
# provider = "prisma-zero"
# }
pnpx prisma generate
```
--------------------------------
### Run a Registered Query
Source: https://zero.rocicorp.dev/docs/queries
Demonstrates how to execute a registered query using `zero.run()`. This example shows fetching all posts using the 'posts.all' query.
```typescript
import {zero} from 'zero.ts'
import {queries} from 'queries.ts'
const allPosts = await zero.run(queries.posts.all())
```
--------------------------------
### Solid Start Query Endpoint Implementation
Source: https://zero.rocicorp.dev/docs/queries
Implement a POST endpoint for Zero.dev queries in a Solid Start application. This handler leverages `handleQueryRequest` for server-side query execution.
```typescript
// src/routes/api/zero/query.ts
import type {APIEvent} from '@solidjs/start/server'
import {handleQueryRequest} from '@rocicorp/zero/server'
import {mustGetQuery} from '@rocicorp/zero'
import {queries} from 'queries.ts'
import {schema} from 'schema.ts'
export async function POST(event: APIEvent) {
const result = await handleQueryRequest({
handler: (name, args) => {
const query = mustGetQuery(queries, name)
return query.fn({args})
},
schema,
request: event.request,
userID: null
})
return Response.json(result)
}
```
--------------------------------
### Install and Generate Prisma Zero with yarn
Source: https://zero.rocicorp.dev/docs/schema.md
Install the prisma-zero package and run the prisma generate command using yarn. Remember to add the generator to your prisma schema.
```bash
yarn add -D prisma-zero
# Add this to your prisma schema:
# generator zero {
# provider = "prisma-zero"
# }
yarn prisma generate
```
--------------------------------
### Set Up Docker Postgres for Zero
Source: https://zero.rocicorp.dev/docs/install
Starts a Docker container for Postgres with logical replication enabled, which is required for Zero to sync data to its SQLite replica.
```bash
# IMPORTANT: logical WAL level is required for Zero
# to sync data to its SQLite replica
docker run -d --name zero-postgres \
-e POSTGRES_DB="zero" \
-e POSTGRES_PASSWORD="pass" \
-p 5432:5432 \
postgres:18 \
postgres -c wal_level=logical
```
--------------------------------
### Analyze query output example
Source: https://zero.rocicorp.dev/docs/debug/analyze-query-cli
This is an example of the output you can expect from the Analyze Query CLI, including query statistics, rows scanned, and query plans.
```text
=== Query Stats: ===
total synced rows: 10
albums vended: {
'SELECT "id","title","artist_id","release_year","cover_art_url","created_at","_0_version" FROM "albums" WHERE "artist_id" = ? ORDER BY "created_at" asc, "id" asc': 10
}
Rows Read (into JS): 10
time: 3.12ms
=== Rows Scanned (by SQLite): ===
albums: {
'SELECT "id","title","artist_id","release_year","cover_art_url","created_at","_0_version" FROM "albums" WHERE "artist_id" = ? ORDER BY "created_at" asc, "id" asc': 25
}
total rows scanned: 25
=== Query Plans: ===
query SELECT "id","title","artist_id","release_year","cover_art_url","created_at","_0_version" FROM "albums" WHERE "artist_id" = ? ORDER BY "created_at" asc, "id" asc
SCAN albums
USE TEMP B-TREE FOR ORDER BY
```
--------------------------------
### Solid Start Query API Endpoint
Source: https://zero.rocicorp.dev/docs/auth
Implement a POST handler for query requests using Solid Start. Authenticates the user and handles the query request with Zero.
```typescript
// src/routes/api/zero/query.ts
import type {APIEvent} from '@solidjs/start/server'
import {handleQueryRequest} from '@rocicorp/zero/server'
import {mustGetQuery} from '@rocicorp/zero'
import {queries} from 'queries.ts'
import {schema} from 'schema.ts'
export async function POST(event: APIEvent) {
const session = await authenticate(
event.request.headers.get('Cookie')
)
const result = await handleQueryRequest({
handler: (name, args) => {
const query = mustGetQuery(queries, name)
return query.fn({
args,
ctx: session?.user
})
},
schema,
request: event.request,
userID: session?.user?.id
})
return Response.json(result)
}
```
--------------------------------
### SolidStart ZeroProvider Setup
Source: https://zero.rocicorp.dev/docs/install
Configures the ZeroProvider within a SolidStart application's main app component. Ensure the schema is correctly imported.
```tsx
// src/app.tsx
import {MetaProvider, Title} from '@solidjs/meta'
import {Router} from '@solidjs/router'
import {FileRoutes} from '@solidjs/start/router'
import {ZeroProvider} from '@rocicorp/zero/solid'
import type {ZeroOptions} from '@rocicorp/zero'
import {Suspense} from 'solid-js'
import {schema} from './zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema
}
export default function App() {
return (
(
Zero App
{props.children}
)}
>
)
}
```
--------------------------------
### Configure Prisma for Zero Schema Generation (yarn)
Source: https://zero.rocicorp.dev/docs/install
Installs prisma-zero and provides instructions to add the generator to prisma/schema.prisma for Zero schema generation using yarn.
```bash
yarn add -D prisma-zero
# Add this to prisma/schema.prisma:
# generator zero {
# provider = "prisma-zero"
# output = "../src/zero"
# }
yarn prisma generate
```
--------------------------------
### Next.js ZeroProvider Setup
Source: https://zero.rocicorp.dev/docs/install
Sets up ZeroProvider in a Next.js application. This involves a dedicated providers file and integration into the root layout.
```tsx
// src/app/providers.tsx
'use client'
import {ZeroProvider} from '@rocicorp/zero/react'
import type {ZeroOptions} from '@rocicorp/zero'
import type {ReactNode} from 'react'
import {schema} from '../zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema
}
export function Providers({
children
}: {children: ReactNode
}) {
return {children}
}
// src/app/layout.tsx
import type {ReactNode} from 'react'
import {Providers} from './providers'
export default function RootLayout({
children
}: {children: ReactNode
}) {
return (
{children}
)
}
```
--------------------------------
### SolidStart ZeroProvider Setup
Source: https://zero.rocicorp.dev/docs/tutorial
Integrate Zero with SolidStart by using the ZeroProvider component within your main App component. Configure with cacheURL and schema.
```tsx
// src/app.tsx
import {MetaProvider, Title} from '@solidjs/meta'
import {Router} from '@solidjs/router'
import {FileRoutes} from '@solidjs/start/router'
import {ZeroProvider} from '@rocicorp/zero/solid'
import type {ZeroOptions} from '@rocicorp/zero'
import {Suspense} from 'solid-js'
import {schema} from './zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema
}
export default function App() {
return (
(
Zero Music
{props.children}
)}
>
)
}
```
--------------------------------
### Register Mutators with Zero Client (TanStack Start)
Source: https://zero.rocicorp.dev/docs/install
Example of registering mutators with the Zero client options in a TanStack Start application.
```typescript
// src/routes/__root.tsx
import type {ZeroOptions} from '@rocicorp/zero'
import {mutators} from '../zero/mutators'
import {schema} from '../zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema,
mutators
}
```
--------------------------------
### Create SolidStart Project with bun
Source: https://zero.rocicorp.dev/docs/tutorial
Initialize a SolidStart project using bun.
```bash
bun create solid zero-music basic --solidstart --ts --v2
cd zero-music
bun install
```
--------------------------------
### Watch Zero.db Database
Source: https://zero.rocicorp.dev/docs/tutorial
Use the 'watch' command to monitor changes in the Zero.db database. Ensure 'watch' is installed via Homebrew.
```bash
watch -n 0.5 "npx @rocicorp/zero-sqlite3 ./zero.db \"SELECT * FROM albums ORDER BY created_at;\""
```
--------------------------------
### Create SolidStart Project with npm
Source: https://zero.rocicorp.dev/docs/tutorial
Initialize a SolidStart project using npm.
```bash
npm init solid -- zero-music basic --solidstart --ts --v2
cd zero-music
npm install
```
--------------------------------
### Tanstack Start API Query Handler with Cookie Auth
Source: https://zero.rocicorp.dev/docs/auth
Example of handling POST requests in Tanstack Start to authenticate using cookies.
```typescript
// src/routes/api/zero/query.ts
import {createFileRoute} from '@tanstack/react-router'
export const Route = createFileRoute('/api/zero/query')({
server: {
handlers: {
POST: async ({request}) => {
const session = await authenticate(
request.headers.get('Cookie')
)
// ... handle query ...
}
}
}
})
```
--------------------------------
### Next.js ZeroProvider Setup
Source: https://zero.rocicorp.dev/docs/tutorial
Set up ZeroProvider in your Next.js application. This involves creating a providers component and integrating it into the root layout.
```tsx
// src/app/providers.tsx
'use client'
import {ZeroProvider} from '@rocicorp/zero/react'
import type {ZeroOptions} from '@rocicorp/zero'
import type {ReactNode} from 'react'
import {schema} from '../zero/schema'
const opts: ZeroOptions = {
cacheURL: 'http://localhost:4848',
schema
}
export function Providers({
children
}: {children: ReactNode}) {
return {children}
}
// src/app/layout.tsx
import type {ReactNode} from 'react'
import {Providers} from './providers'
export default function RootLayout({
children
}: {children: ReactNode}) {
return (
{children}
)
}
```
--------------------------------
### Trigger Resend on Server POST Error (Tanstack Start)
Source: https://zero.rocicorp.dev/docs/mutators
Example of throwing an error in a Tanstack Start POST handler to trigger a client-side resend of queued mutations.
```typescript
export const Route = createFileRoute('/api/zero/mutate')({
server: {
handlers: {
POST: async () => {
throw new Error('zonk') // will trigger resend
}
}
}
})
```
--------------------------------
### Create SolidStart Project with pnpm
Source: https://zero.rocicorp.dev/docs/tutorial
Initialize a SolidStart project using pnpm.
```bash
pnpm create solid zero-music basic --solidstart --ts --v2
cd zero-music
pnpm install
```
--------------------------------
### Drizzle Database Provider Setup
Source: https://zero.rocicorp.dev/docs/server-zql
Configure the Drizzle adapter for Zero. Pass a Drizzle client instance to `zeroDrizzle`. Register the provider for type safety.
```typescript
// app/api/mutate/db-provider.ts
import {zeroDrizzle} from '@rocicorp/zero/server/adapters/drizzle'
import {schema} from '../../zero/schema.ts'
import * as drizzleSchema from '../../drizzle/schema.ts'
// pass a drizzle client instance. for example:
export const drizzleClient = drizzle(pool, {
schema: drizzleSchema
})
export const dbProvider = zeroDrizzle(schema, drizzleClient)
// Register the database provider for type safety
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Set Up Postgres.app for Zero
Source: https://zero.rocicorp.dev/docs/install
Configures a local Postgres instance using Postgres.app, ensuring logical replication is enabled and setting a password. Requires Postgres 15 or higher.
```bash
# Start Postgres.app first. Requires Postgres 15 or higher.
# If these already exist, you can skip those commands.
createuser -s postgres
createdb -O postgres zero
psql -d postgres -c "ALTER USER postgres WITH PASSWORD 'pass';"
psql -d postgres -c "ALTER SYSTEM SET wal_level = 'logical';"
# Restart Postgres.app, then verify:
psql -d postgres -c "SHOW wal_level;"
```
--------------------------------
### postgres.js Database Provider Setup
Source: https://zero.rocicorp.dev/docs/server-zql
Configure the postgres.js adapter for Zero. Initialize `postgres` with a connection string and pass the instance to `zeroPostgresJS`. Register the provider for type safety.
```typescript
// app/api/mutate/db-provider.ts
import {zeroPostgresJS} from '@rocicorp/zero/server/adapters/postgresjs'
import postgres from 'postgres'
import {schema} from '../../zero/schema.ts'
const sql = postgres(process.env.ZERO_UPSTREAM_DB!)
export const dbProvider = zeroPostgresJS(schema, sql)
// Register the database provider for type safety
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Prisma Database Provider Setup
Source: https://zero.rocicorp.dev/docs/server-zql
Configure the Prisma adapter for Zero. Initialize Prisma Client with a PrismaPg adapter and connection string, then pass it to `zeroPrisma`. Register the provider for type safety.
```typescript
// app/api/mutate/db-provider.ts
import {PrismaPg} from '@prisma/adapter-pg'
import {PrismaClient} from '@prisma/client'
import {zeroPrisma} from '@rocicorp/zero/server/adapters/prisma'
import {schema} from '../../zero/schema.ts'
const prisma = new PrismaClient({
adapter: new PrismaPg({
connectionString: process.env.ZERO_UPSTREAM_DB!
})
})
export const dbProvider = zeroPrisma(schema, prisma)
// Register the database provider for type safety
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Drizzle DB Provider Setup
Source: https://zero.rocicorp.dev/docs/install
Configure the Drizzle ORM with the Postgres adapter for Zero. Ensure your database client is installed and the ZERO_UPSTREAM_DB environment variable is set.
```typescript
// src/zero/db-provider.ts
import {zeroDrizzle} from '@rocicorp/zero/server/adapters/drizzle'
import {drizzle} from 'drizzle-orm/node-postgres'
import {Pool} from 'pg'
import {schema} from './schema'
import * as drizzleSchema from '../drizzle/schema'
// If your app uses a different Drizzle driver, reuse your existing client.
const connectionString = process.env.ZERO_UPSTREAM_DB
if (!connectionString) {
throw new Error('ZERO_UPSTREAM_DB is not set')
}
const pool = new Pool({
connectionString
})
export const drizzleClient = drizzle(pool, {
schema: drizzleSchema
})
export const dbProvider = zeroDrizzle(schema, drizzleClient)
// Register global types for mutators on the server
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Configure Prisma for Zero Schema Generation (bun)
Source: https://zero.rocicorp.dev/docs/install
Installs prisma-zero and provides instructions to add the generator to prisma/schema.prisma for Zero schema generation using bun.
```bash
bun add -D prisma-zero
# Add this to prisma/schema.prisma:
# generator zero {
# provider = "prisma-zero"
# output = "../src/zero"
# }
bunx prisma generate
```
--------------------------------
### Setup ZeroProvider in SolidJS
Source: https://zero.rocicorp.dev/docs/solidjs
Use `ZeroProvider` to set up Zero instances reactively. It handles creating and destroying `Zero` instances. Pass authentication details and schema/mutators here. Omit `userID` when the user is logged out.
```tsx
import {ZeroProvider} from '@rocicorp/zero/solid'
import {useSession} from 'my-auth-provider'
import App from 'App.tsx'
import {schema} from 'schema.ts'
import {mutators} from 'mutators.ts'
const cacheURL = import.meta.env.VITE_PUBLIC_ZERO_CACHE_URL!
function Root() {
const session = useSession()
const userID = session?.userID
const auth = session?.accessToken
const context = userID ? {userID} : undefined
return (
)
}
```
--------------------------------
### Kysely Database Provider Setup
Source: https://zero.rocicorp.dev/docs/server-zql
Configure the Kysely adapter for Zero. Initialize Kysely with a Postgres dialect and pool, then pass it to `zeroKysely`. Register the provider for type safety.
```typescript
// app/api/mutate/db-provider.ts
import {Kysely, PostgresDialect} from 'kysely'
import {zeroKysely} from '@rocicorp/zero/server/adapters/kysely'
import {Pool} from 'pg'
import {schema} from '../../zero/schema.ts'
interface Database {
user: {
id: string
name: string | null
status: 'active' | 'inactive'
}
}
const kysely = new Kysely({
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.ZERO_UPSTREAM_DB!
})
})
})
export const dbProvider = zeroKysely(schema, kysely)
// Register the database provider for type safety
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Invoke Query with TanStack Start
Source: https://zero.rocicorp.dev/docs/tutorial
Fetches albums for a specific artist using useQuery in a TanStack Start application.
```tsx
// src/routes/index.tsx
import {createFileRoute} from '@tanstack/react-router'
import {useQuery} from '@rocicorp/zero/react'
import {queries} from '../zero/queries'
export const Route = createFileRoute('/')({
component: Home
})
function Home() {
const [albums] = useQuery(
queries.albums.byArtist({artistId: 'artist_1'})
)
return (
{albums.map(album => (
- {album.title}
))}
)
}
```
--------------------------------
### Configure Prisma for Zero Schema Generation (npm)
Source: https://zero.rocicorp.dev/docs/install
Installs prisma-zero and provides instructions to add the generator to prisma/schema.prisma for Zero schema generation using npm.
```bash
npm install -D prisma-zero
# Add this to prisma/schema.prisma:
# generator zero {
# provider = "prisma-zero"
# output = "../src/zero"
# }
npx prisma generate
```
--------------------------------
### Install Zero and Zod with yarn
Source: https://zero.rocicorp.dev/docs/install
Installs Zero and Zod using yarn. Requires adding the package to package.json and rebuilding native packages.
```bash
yarn add @rocicorp/zero zod
# Note: Modern Yarn doesn't run postinstall scripts by default.
# Add to package.json, then rebuild the native packages:
# "dependenciesMeta": {
# "@rocicorp/zero-sqlite3": {
# "built": true
# }
# }
yarn rebuild @rocicorp/zero-sqlite3
```
--------------------------------
### Configure Prisma for Zero Schema Generation (pnpm)
Source: https://zero.rocicorp.dev/docs/install
Installs prisma-zero and provides instructions to add the generator to prisma/schema.prisma for Zero schema generation using pnpm.
```bash
pnpm add -D prisma-zero
# Add this to prisma/schema.prisma:
# generator zero {
# provider = "prisma-zero"
# output = "../src/zero"
# }
pnpx prisma generate
```
--------------------------------
### Install Zero and Zod with bun
Source: https://zero.rocicorp.dev/docs/install
Installs Zero and Zod using bun. Requires trusting the native package build or adding it to package.json.
```bash
bun add @rocicorp/zero zod
# Note: Bun disables postinstall scripts by default for security.
# Either approve the build:
bun pm trust @rocicorp/zero-sqlite3
# Or add to package.json, then rebuild the native packages:
# "trustedDependencies": ["@rocicorp/zero-sqlite3"]
```
--------------------------------
### Install Zero and Zod with pnpm
Source: https://zero.rocicorp.dev/docs/install
Installs Zero and Zod using pnpm. Requires enabling builds for the native package in pnpm-workspace.yaml and rebuilding.
```bash
pnpm add @rocicorp/zero zod
# Note: pnpm disables postinstall scripts by default for security.
# Create or update pnpm-workspace.yaml to allow the native package build:
# https://pnpm.io/settings#allowbuilds
# allowBuilds:
# '@rocicorp/zero-sqlite3': true
pnpm rebuild @rocicorp/zero-sqlite3
```
--------------------------------
### Create TanStack Project with bun
Source: https://zero.rocicorp.dev/docs/tutorial
Use the TanStack CLI to create a new project with bun as the package manager.
```bash
bunx @tanstack/cli@latest create zero-music \
--package-manager bun --yes --no-intent
cd zero-music
```
--------------------------------
### Tanstack Start Mutate Handler
Source: https://zero.rocicorp.dev/docs/auth
Handles POST requests for mutations in a Tanstack Start application. Requires authentication and uses Zero's handleMutateRequest.
```typescript
// src/routes/api/zero/mutate.ts
import {createFileRoute} from '@tanstack/react-router'
import {handleMutateRequest} from '@rocicorp/zero/server'
import {mustGetMutator} from '@rocicorp/zero'
import {mutators} from 'mutators.ts'
import {dbProvider} from 'db-provider.ts'
export const Route = createFileRoute('/api/zero/mutate')({
server: {
handlers: {
POST: async ({request}) => {
const session = await authenticate(
request.headers.get('Authorization')
)
const result = await handleMutateRequest({
dbProvider,
handler: transact =>
transact((tx, name, args) => {
const mutator = mustGetMutator(mutators, name)
return mutator.fn({
args,
tx,
ctx: session?.user
})
}),
request,
userID: session?.user?.id
})
return Response.json(result)
}
}
}
})
```
--------------------------------
### Create Next.js Project with npm
Source: https://zero.rocicorp.dev/docs/tutorial
Use create-next-app to scaffold a new project with npm.
```bash
npx create-next-app@latest zero-music --yes --use-npm
cd zero-music
```
--------------------------------
### Create Next.js Project with bun
Source: https://zero.rocicorp.dev/docs/tutorial
Use create-next-app to scaffold a new project with bun.
```bash
npx create-next-app@latest zero-music --yes --use-bun
cd zero-music
```
--------------------------------
### Solid Start Mutate Handler
Source: https://zero.rocicorp.dev/docs/auth
Handles POST requests for mutations within a Solid Start application. Integrates with Zero's server-side mutation handling.
```typescript
// src/routes/api/zero/mutate.ts
import type {APIEvent} from '@solidjs/start/server'
import {handleMutateRequest} from '@rocicorp/zero/server'
import {mustGetMutator} from '@rocicorp/zero'
import {mutators} from 'mutators.ts'
import {dbProvider} from 'db-provider.ts'
export async function POST(event: APIEvent) {
const session = await authenticate(
event.request.headers.get('Authorization')
)
const result = await handleMutateRequest({
dbProvider,
handler: transact =>
transact((tx, name, args) => {
const mutator = mustGetMutator(mutators, name)
return mutator.fn({
args,
tx,
ctx: session?.user
})
}),
request: event.request,
userID: session?.user?.id
})
return Response.json(result)
}
```
--------------------------------
### Set Up Zero Database Connection URL
Source: https://zero.rocicorp.dev/docs/install
Creates a .env file to specify the Zero upstream database connection URL, ensuring consistency between the app server and zero-cache-dev.
```bash
# Update to your app's database connection URL
ZERO_UPSTREAM_DB="postgres://postgres:pass@localhost:5432/zero"
```
--------------------------------
### TanStack Start Mutate Endpoint Handler
Source: https://zero.rocicorp.dev/docs/install
Implement the POST handler for the mutate endpoint using TanStack Start. This integrates Zero's `handleMutateRequest` with your custom mutators and the configured `dbProvider`.
```typescript
// src/routes/api/mutate.ts
import {createFileRoute} from '@tanstack/react-router'
import {handleMutateRequest} from '@rocicorp/zero/server'
import {mustGetMutator} from '@rocicorp/zero'
import {mutators} from '../../zero/mutators'
import {dbProvider} from '../../zero/db-provider'
export const Route = createFileRoute('/api/mutate')({
server: {
handlers: {
POST: async ({request}) => {
const result = await handleMutateRequest({
dbProvider,
handler: transact =>
transact((tx, name, args) => {
const mutator = mustGetMutator(mutators, name)
return mutator.fn({args, tx})
}),
request,
userID: null
})
return Response.json(result)
}
}
}
})
```
--------------------------------
### Seed Music Database with psql
Source: https://zero.rocicorp.dev/docs/tutorial
Downloads and executes a SQL script to create music-themed tables and populate them with sample data in the specified Postgres database.
```bash
# Creates new albums, artists, fans,
# and favorites tables with sample music data
curl -L https://raw.githubusercontent.com/rocicorp/zero-music/1-install/migrations/0000_seed_music.sql \
| psql postgres://postgres:pass@localhost:5432/zero
```
--------------------------------
### Handle Mutate Request with Async Tasks in Solid Start
Source: https://zero.rocicorp.dev/docs/mutators
A Solid Start API route handler for Zero mutations. It sets up `createMutators` to queue asynchronous operations, which are then executed independently of the HTTP response.
```typescript
export async function POST(event: APIEvent) {
const asyncTasks: Array<() => Promise> = []
const mutators = createMutators(asyncTasks)
const result = await handleMutateRequest({
dbProvider,
handler: transact =>
transact((tx, name, args) => {
const mutator = mustGetMutator(mutators, name)
return mutator.fn({tx, args})
}),
request: event.request,
userID: null
})
// Run all async tasks
// If any fail, do not block the response, since the
// mutation result has already been written to the database.
await Promise.allSettled(asyncTasks.map(task => task()))
return Response.json(result)
}
```
--------------------------------
### Convert AST to ZQL with Schema Mapping
Source: https://zero.rocicorp.dev/docs/debug/query-asts
Provide a schema file to map server names back to client names in the generated ZQL query. This is useful when using the `from` feature in your schema for different client and backend names.
```bash
cat ast.json | npx ast-to-zql --schema schema.ts
```
--------------------------------
### node-postgres Database Provider Setup
Source: https://zero.rocicorp.dev/docs/server-zql
Configure the node-postgres adapter for Zero. Create a `pg.Pool` instance with a connection string and pass it to `zeroNodePg`. Register the provider for type safety.
```typescript
// app/api/mutate/db-provider.ts
import {zeroNodePg} from '@rocicorp/zero/server/adapters/pg'
import {Pool} from 'pg'
import {schema} from '../../zero/schema.ts'
const pool = new Pool({
connectionString: process.env.ZERO_UPSTREAM_DB!
})
export const dbProvider = zeroNodePg(schema, pool)
// You can also pass a client instead of a pool:
//
// const client = new Client({
// connectionString: process.env.ZERO_UPSTREAM_DB!
// })
// await client.connect()
// export const dbProvider = zeroNodePg(schema, client)
// Register the database provider for type safety
declare module '@rocicorp/zero' {
interface DefaultTypes {
dbProvider: typeof dbProvider
}
}
```
--------------------------------
### Create Custom Publication SQL
Source: https://zero.rocicorp.dev/docs/zero-cache-config
Example SQL statements for creating custom publications in PostgreSQL for zero-cache.
```sql
CREATE PUBLICATION zero_data FOR TABLES IN SCHEMA public;
-- or, more selectively:
CREATE PUBLICATION zero_data FOR TABLE users, orders;
```
--------------------------------
### TypeScript Materialize and Listen
Source: https://zero.rocicorp.dev/docs/queries
Use `zero.materialize` to get a query result and `addListener` to subscribe to its changes in TypeScript.
```ts
import {queries} from 'zero/queries.ts'
import {zero} from 'zero.ts'
const postsView = zero.materialize(
queries.posts.byAuthorID('user123')
)
for (let post of postsView.data) {
console.log(post.title)
}
// updates as the underlying data changes
postsView.addListener(posts => {
console.log('posts', posts)
})
```
--------------------------------
### Generate Zero Schema with Drizzle (yarn)
Source: https://zero.rocicorp.dev/docs/install
Installs drizzle-zero and generates the Zero schema file using yarn.
```bash
yarn add -D drizzle-zero
yarn exec drizzle-zero generate --output src/zero/schema.ts
```
--------------------------------
### Set up analyze-query script
Source: https://zero.rocicorp.dev/docs/debug/analyze-query-cli
Create a script to import your schema and call runAnalyzeCLI. This allows the CLI to evaluate query strings using your client-side schema definitions.
```typescript
// scripts/analyze.ts
import {runAnalyzeCLI} from '@rocicorp/zero/analyze'
import {schema} from '../src/zero/schema.ts'
await runAnalyzeCLI({schema})
```
--------------------------------
### Generate Zero Schema with Drizzle (npm)
Source: https://zero.rocicorp.dev/docs/install
Installs drizzle-zero and generates the Zero schema file using npm.
```bash
npm install -D drizzle-zero
npx drizzle-zero generate --output src/zero/schema.ts
```