# Quickstart

> From nothing to the demo directory running on your machine — with create-zerodirs or from the repository you were given.

You are reading one page of the ZeroDirs documentation. ZeroDirs is a paid Astro + Cloudflare Workers starter for directory sites: every page is rendered to static HTML at build time, the site ships no client JavaScript outside `/search/`, and one file — `site.config.ts` — carries roughly 80% of the customisation.

Two things to hold on to before you act on anything below:

- `site.config.ts` is validated by a zod schema with ten cross-field rules. After any edit to it, run `pnpm check:config`; every problem is reported as `site.config.ts › <path>: <message>` and the whole file is checked at once.
- The repository ships its own `AGENTS.md` with twenty hard rules, and a machine-checked test suite behind them. If you are working inside a ZeroDirs project, read that file first — it overrides anything general you infer from this page.

Source: https://zerodirs.com/docs/start/quickstart/

---

Two routes to a running directory: the CLI scaffolds a project and asks you a few questions; cloning
the repository gives you the starter exactly as it ships, demo data included. Both end at the same
place — `pnpm dev`, and the demo site on your machine with no account, no key and no database of
your own.

## Before you start

| You need | Check | You should see |
| --- | --- | --- |
| Node 22.18 or newer — Node 24 is what the starter is tested on and what `.nvmrc` pins | `node --version` | `v24.x.x` (or `v22.18.0` and up) |
| pnpm — the repository pins the version in `package.json`, and `corepack enable` installs that one | `pnpm --version` | a `10.x` version |
| git — to clone, and to pull updates later | `git --version` | any version |

wrangler is a dependency of the project, not something you install: `pnpm exec wrangler` runs the
pinned one.

## Install

**With the CLI**

1. Scaffold.

   ```sh title="Terminal"
   npm  create zerodirs@latest my-directory -- --pro   # npm needs the `--`
   pnpm create zerodirs        my-directory --pro
   yarn create zerodirs        my-directory --pro
   bun  create zerodirs        my-directory --pro
   ```

   Without `--pro` you get the free MIT edition, which is the same code with the paid half
   deleted — see [Free vs Pro](https://zerodirs.com/docs/about/free-vs-pro/). With `--pro` the CLI clones the private
   starter repository using **your own** git credentials; it never handles a licence key and never
   signs you in to anything.

2. Answer the questions.

   The site name, the domain, a sample dataset, a theme, and — on the paid template — whether you
   want public submissions and how you want to send email. `--yes` skips all of it and takes the
   conservative answer to every question: no submissions, no payments, `console` email, the free
   plan. Each alternative needs an account or a key a non-interactive run cannot have, so `--yes`
   refusing them is the point.

   ```text
   create-zerodirs [directory] [options]

     --pro                    Use the paid starter template (default: the free MIT edition)
     --dataset <name>         ai-tools | indie-tools | local-businesses
     --template-dir <path>    Copy from a local directory instead of fetching a release
                              (env: ZERODIRS_TEMPLATE_DIR)
     --name <name>            Site name
     --domain <host>          Production domain, e.g. dir.example.com
     --theme <preset>         default | warm | mono
     --package-manager <pm>   pnpm | npm | yarn | bun
     -y, --yes                Accept every default; ask nothing
     --no-cloudflare          Never call wrangler; create no Cloudflare resources
     --no-install             Do not install dependencies
   ```

3. Read `SETUP.md`.

   The CLI rewrites `site.config.ts` through its AST, so the file keeps its comments and keeps
   type-checking; the same for `wrangler.jsonc`. It generates `.dev.vars` with a fresh
   `ADMIN_SECRET` and `TOKEN_SECRET`, loads the chosen dataset into `src/content/`, and writes a
   `SETUP.md` listing everything it deliberately left to you. It does **not** sign you in, upload a
   secret, run a deploy, write to a remote database, run `git init`, install anything globally,
   send telemetry, or overwrite a directory that already has files in it.

   The site's whole shape — the URL scheme, the noun for a listing, the structured-data type, the
   categories and tags — comes from the dataset's own `meta.json`. A dataset declaring
   `kind: "business"` produces `seo.jsonLd.listing: 'localBusiness'`, which is what makes the
   detail pages emit LocalBusiness structured data.

**From the repository**

1. Clone it.

   A purchase gives you read access to the starter repository; clone it under the name you want
   the project to have.

   ```sh title="Terminal"
   git clone git@github.com:zerodirs/zerodirs.git my-directory
   cd my-directory
   ```

2. Install.

   ```sh title="Terminal"
   pnpm install
   ```

   `postinstall` copies the agent skills into `.claude/skills/`; that is the only thing it does.

## Run it

```sh title="Terminal"
pnpm dev
```

Before the dev server starts, `pnpm dev` does three things a fresh clone would otherwise discover
one error at a time, and prints a line for each:

```text
dev: wrote .env from .env.example — LISTINGS_SOURCE=files, the default for a local build
dev: wrote .dev.vars from .dev.vars.example — placeholder secrets for local development; pnpm cf:setup replaces them
dev: applied 2 migrations to the local D1 (.wrangler/state)
```

It never touches a Cloudflare account and never writes over a file that exists. On the next run
the first two lines are gone and the third says `dev: local D1 is up to date`.

### Verify

| | Open | You should see |
| --- | --- | --- |
| The site | `http://localhost:4321/` | the demo directory: the AI-tools dataset, its categories and tags |
| Submissions | `http://localhost:4321/submit/` | the first step of the form. It works locally against the Miniflare database that was just migrated |
| The admin | `http://localhost:4321/admin/login/` | the login form. The password is `ADMIN_SECRET` in `.dev.vars` — a placeholder, and the configuration report on `/admin/` says so |

> **Search finds nothing under pnpm dev**
>
> Pagefind only indexes during a real build. `pnpm build`, then `pnpm preview`, is how to try search
> locally. This is correct behaviour, not a bug in the search island.

> **Free edition**
>
> `pnpm dev` there is just the Astro dev server: no database, no `/submit/`, no `/admin/`.

## Next

- [Make it yours](https://zerodirs.com/docs/start/make-it-yours/) — The first hour after the dev server runs — name it, replace the demo content, brand it, switch things on.
- [Go live](https://zerodirs.com/docs/deploy/go-live/) — One command to your own domain, then the short list of things only you can do.
- [Listings and datasets](https://zerodirs.com/docs/configure/data/) — The Markdown contract, the importer, datasets, and moving to a database.
- [Working with an agent](https://zerodirs.com/docs/agents/overview/) — Read this before the first prompt if you plan to hand it to Claude Code or Cursor.
