### 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 ```