What you are buying
ZeroDirs is source you own, not a hosted service and not a subscription. What arrives is a flat copy of one directory: an Astro project with a Cloudflare Workers adapter, its content, its tests and its documentation. You install it, you change it, you deploy it to your own Cloudflare account, and nothing in it calls home.
There is no license key, no runtime check and no ZeroDirs API. If this site went away tomorrow, every copy already sold would keep building.
The measured claims
Section titled “The measured claims”Every number on this site comes from a command you can run in your own copy. These are the ones worth checking first, because they are the ones the product is sold on.
| Claim | How it is measured | Where |
|---|---|---|
| 433 pages from 145 listings in about two seconds | pnpm build on the demo dataset |
the build log |
| 211 of them programmatic SEO | pseo: generated 211 in the build log |
integrations/seo-report.ts |
| 0 orphan pages | seo.strictLinks: true fails the build on a listing with fewer than 2 inbound links |
integrations/seo-report.ts |
Zero client JavaScript outside /search/ |
the build fails on any <astro-island> or <script src> elsewhere |
integrations/budget.ts |
| 1.00 Lighthouse performance, 9 templates | pnpm lhci, 5 runs per URL, desktop and mobile configs |
lighthouserc.cjs |
| 978 unit tests and 402 Workers tests, plus an end-to-end Playwright suite | pnpm test, pnpm test:workers, pnpm test:e2e |
— |
| The free edition uploads no Worker script | wrangler deploy --dry-run reports 0.34 KiB and no script |
see Free vs Pro |
The Lighthouse and zero-JavaScript claims are the two that matter most, because they are the two
that a normal starter loses the moment you change anything. Both are enforced by the build rather
than asserted in a README: the zero-JavaScript rule is a build integration that fails on an
unexpected island, and pnpm lhci audits your pages from your route manifest, so replacing
all 145 demo listings with your own does not invalidate the number — it re-measures it.
What is in the box
Section titled “What is in the box”The directory itself. Listings, categories, tags, pagination, a detail page per listing,
related listings, custom per-listing fields, a blog with its own feed, a site-wide feed of recent
listings, and full-text search. Content comes from Markdown files, or from Cloudflare D1 when you
switch LISTINGS_SOURCE.
Search engine plumbing that is normally an afterthought. A chunked sitemap, robots.txt,
canonical URLs including on paginated pages, JSON-LD chosen from your site.kind, noindex on
thin taxonomy pages, Open Graph images rendered at build time in your own theme colours, and a
build-time report that counts inbound internal links per listing and can fail the build on
orphans.
Programmatic SEO as a first-class feature. Two configurable patterns generate long-tail landing pages from your own categories and tags, with a thin-content guard so a page with three matching listings never gets built, and a hard page cap so the file budget cannot run away.
The submission pipeline. A two-step public submission form, three configurable plans, Stripe Checkout for the paid ones, a signed-token status page that needs no account, an admin review queue behind a single secret, transactional email, and an automatic rebuild when you approve something.
Everything an agent needs to work in it. An AGENTS.md whose rules are checked by the test
suite, ten skills for the jobs you will repeat, and a site.config.ts that reports every
problem at once with the exact field path.
What it deliberately does not do
Section titled “What it deliberately does not do”This list is as much of the product as the last one. Each of these is a decision, not a gap.
- No passwords, no profiles. A submitter signs in with an emailed link or with Google, and their account is the list of their own submissions and nothing more. There is one admin, authenticated with one secret.
- No rich admin UI. The review queue is server-rendered forms. Approving something is a POST and a page refresh. This is a deliberate trade against the Workers free plan’s 10 ms of CPU per request.
- No reviews, ratings or comments. Rich results for ratings on directory listings no longer exist in Google, so the schema would be decoration with a moderation problem attached.
- No multi-language build.
site.localesets the document language; it does not produce a second tree of pages. - No CMS. Your content is Markdown in your repository or rows in your D1 database, and both are yours to edit with the tools you already have.
- No analytics. Add whatever you use; nothing is embedded for you.
What you need
Section titled “What you need”Node 24 (22.18 is the floor), pnpm 10.12.4, and — only when you deploy — a Cloudflare account. Nothing about running it locally requires an account, an API key, a database or a paid service.
Stripe and Resend accounts matter only if you turn on paid submissions and email. Both degrade to inert defaults rather than failing the build when their secrets are missing.
- Quickstart — one command to a project that builds.
- Free vs Pro — there is an MIT edition; here is exactly what it is missing and why.
- Cost and limits — the $0/month boundary, in files rather than adjectives.