Overview

Quartz 4 builds to public/ and serves a hot-reload preview on port 8080. This guide takes a fresh checkout to a running local site in under five minutes. It covers the install path, the dev server, and the four errors most new users hit. The umbrella rules and quartz.config.ts patterns live in quartz.

Prerequisites

  • Node 22. Older Node versions throw cryptic ESM errors at build. Check with node -v.
  • npm 10 or newer. Comes with Node 22.
  • Git, to clone the repo.
  • 200 MB of free disk for node_modules.

Steps

1. Clone the repo

git clone https://github.com/<you>/<your-quartz-repo>.git
cd <your-quartz-repo>

If you are starting from upstream Quartz, clone https://github.com/jackyzha0/quartz.git and rename the directory to your site name.

2. Pin Node 22

Node version drift causes silent build differences. Use nvm or a similar manager to pin Node 22 per-project.

nvm install 22
nvm use 22
node -v   # expected: v22.x.x

If the repo has a .nvmrc, nvm use picks the right version automatically.

3. Install dependencies

npm ci

Use npm ci, not npm install. ci honors package-lock.json exactly; install may update transitive deps and break the build.

4. Run the dev server

npx quartz build --serve

The first build takes 20 to 60 seconds depending on vault size. The server then listens on http://localhost:8080 and rebuilds on file changes. Open the URL in a browser; the master MOC at content/index.md is the landing page.

5. Edit and watch the rebuild

Edit any file under content/. The terminal shows Detected change and rebuilds. The browser auto-reloads via the dev server’s websocket.

If the rebuild fails, the terminal prints the offending file and line. Fix and save; the next save triggers a clean rebuild.

6. Build for production

Before opening a PR, run a clean production build to catch errors the dev server forgives.

rm -rf public .quartz-cache
npx quartz build

If this exits 0, the build is shippable. See deploy-quartz-site for the GitHub Pages deploy.

Verify it worked

Three checks.

# 1. Dev server returns 200 on the homepage.
curl -sI http://localhost:8080/ | head -1
# expected: HTTP/1.1 200 OK
 
# 2. The build produced public/index.html.
ls public/index.html
# expected: file exists
 
# 3. A known page renders.
curl -s http://localhost:8080/ | grep -o '<title>[^<]*</title>'
# expected: the configured pageTitle

Common errors

  • EADDRINUSE: address already in use :::8080. Another dev server is running. Kill it with lsof -i :8080 then kill <pid>, or pass a different port: npx quartz build --serve --port 8081.
  • Cannot find module '@myriaddreamin/rehype-typst' or similar. Dependencies are stale. Delete node_modules and .quartz-cache, then npm ci.
  • Build hangs at “Parsing files”. Quartz is processing a corrupted markdown file. Run npx quartz build --verbose to find the file, then check for unclosed code fences or invalid frontmatter.
  • Theme renders broken. The theme block in quartz.config.ts references a font or color that does not exist. Compare against the default config in the upstream Quartz repo; restore the missing field.
  • Plugins emit in the wrong order. Plugin.ContentIndex must run before Plugin.Static, or the sitemap is empty. Keep the emitter list in the order from quartz; do not alphabetize it.
  • fatal: not a git repository when Quartz computes dates. The vault must be a git repo for CreatedModifiedDate({ priority: ["git"] }). Either git init the project, or set the priority to ["frontmatter"] only.
  • Wikilinks render as plain text. The link target does not exist or the slug is wrong. Quartz only resolves wikilinks to existing pages; create the target page or fix the slug.