Skip to content
zap.ts
Esc
navigateopen⌘Jpreview
On this page

Project structure

What each folder in zap.ts holds, and the rule that decides where your own code should go.

zap.ts is a monorepo. A monorepo is one repository that holds several projects at once, instead of one repository for each.

There are three top folders.

zap.ts/
├── apps/       things you run and visit
├── packages/   shared code the apps import
└── tooling/    shared settings for tests and TypeScript

The pnpm-workspace.yaml file lists these three folders. That is how pnpm knows they belong together.

apps/ — what you run

Each folder here is a separate website or server.

Folder What it is
web Your product. Users sign in to reach it. Address: app.<domain>
marketing Your public website: home page, blog, legal pages. Address: <domain>
admin Your back office. Address: admin.<domain>
api Your own public API, described with OpenAPI
docs A documentation site for your own product
emails A preview tool for your emails. It runs only on your computer

web, marketing and admin are three separate apps on purpose. A visitor reading your blog should not have to download your whole product first.

The back office keeps its own sign-in, separate from the web app.

api is for the public API you offer your customers. Your own app’s server code does not go there. TanStack Start already runs server code inside web, next to the page that needs it. See API.

packages/ — what the apps share

Each folder here is a library. Apps import them. Nothing is copied.

Folder What it does
database Your tables, and the tool that talks to Postgres
authentication Sign-in, teams, two-factor codes, passkeys
authorization Who is allowed to do what
billing Subscriptions and payments
mail Sending email, and the email designs
storage File uploads
queues Work that runs later, in the background
queues-cloudflare Runs that background work on Cloudflare
queues-vercel Runs that background work on Vercel
ai Talking to AI models
analytics Seeing how people use your app
flags Turning features on and off without a new release
observability Catching and reporting errors
environment Reading your settings and keys safely
ui Buttons, forms, tables and the rest of the visual parts
tanstack-start The shared setup every app uses to start up

tooling/ — shared settings

This folder holds settings, not product code.

  • tsconfig — the shared TypeScript settings every project extends.
  • testing — helpers for tests, such as a temporary test database.
  • vite — shared build settings.

Where should my own code go?

Use this rule.

  1. Only one app needs it, and it will stay that way. Put it in that app.
  2. Two apps need it, or you can see that they soon will. Put it in a new folder under packages/.

Do not create a package for code with one user. Move it later, when a second app actually needs it.

See Adding a package for the steps.

How the parts refer to each other

Inside zap.ts, one package imports another by name:

"@zap-ts/database": "workspace:*"

workspace:* means “the copy in this repository”, not a version downloaded from the internet.

Libraries from outside use a shared version list instead. See Dependencies.

Last updated on September 22, 2026

Was this page helpful?