prestruct docs

All commands and scripts available in prestruct.

prestruct CLI

The prestruct package ships an executable. It runs from any directory that contains a Vite app plus a ssr.config.js:

# Scaffold never-clobber starter files (ssr.config.example.js, public/_headers, src/AppLayout.jsx, ...)
# Existing files are never overwritten -- safe to run on an existing project.
# Activate the config after scaffolding: cp ssr.config.example.js ssr.config.js
npx prestruct init [dir]

# Validate ssr.config.js only: prints every diagnostic line-by-line, exits 1 on a bad config
npx prestruct validate

# Full pipeline: validate -> vite build -> inject-brand -> prerender
# --force rerenders all routes; --clean clears the incremental cache first
npx prestruct build

# Clear the prerender cache for the current project (optional maintenance)
npx prestruct clean

# Verify the baked output without touching it (head hygiene, SVG og:image
# trap, JSON-LD parse, sitemap/robots/404 contract); exit 1 on FAIL rows only
npx prestruct audit

# Show the command reference
npx prestruct help

Install is NOT a CLI verb: npm install / git clone unwraps the package; the verbs the package ships are exactly init, build, validate, audit, clean, and help. All commands except help accept a positional [dir] (explicit workdir); without one they walk up from the current directory until they find ssr.config.js.

To use these as npm scripts instead, add prestruct to devDependencies and wire it up:

{
  "scripts": {
    "build": "prestruct build"
  }
}

Note: the scaffolded init/ app still uses the raw node npm-script forms (below); the CLI is the packaged one-entry-point equivalent.

Template npm scripts

The init/ template ships exactly these. prestruct build is a packaged re-run of the same npm run build pipeline (which now ends with the audit):

{
  "build":    "vite build && node scripts/inject-brand.js && node scripts/prerender.js && node scripts/audit.js",
  "test":     "vitest",
  "test:run": "vitest run",
  "test:ui":  "vitest --ui",
  "lint":     "eslint . --ext js,mjs",
  "lint:fix": "eslint . --ext js,mjs --fix"
}

There is no dev / preview / prerender npm script in the template. Run npx vite dev / npx vite preview directly if you want a local server; the prerender step only ever runs as part of build (or npx prestruct build).

Build pipeline

The build runs three steps in sequence:

npm run build
    |
    |-> vite build          -> JS/CSS bundles in dist/assets/
    |
    |-> inject-brand.js     -> Global meta in index.html
    |
    `-> prerender.js        -> Per-route HTML generation

prestruct build adds a fourth step first:

prestruct build
    |
    |-> validate-config.js  -> structured [prestruct] diagnostics
    |-> vite build
    |-> inject-brand.js
    `-> prerender.js

Config loading is fixed in every entry point: ssr.config.js from the explicit [dir] argument (default: current directory, walking up to the nearest parent that has one). There is currently no --config flag.

Flag notes backed by the CLI dispatch (bin/cli.mjs):

The audit subcommand

prestruct audit [dist] reads the baked output (never writes) and grades it:

The scaffolded init//example apps run the audit straight after prerender in their build script, so a regression fails the build rather than shipping.

Deploy commands (prestruct output is what deploys)

prestruct build output is the only artifact that ships. On Cloudflare Pages, that’s normally git-connected (push to main -> Pages runs npm run build, serves dist/ – full setup: Cloudflare Pages guide). For direct uploads the wrangler commands operate on prestruct’s dist/:

npm run build            # or: npx prestruct build

# First direct upload
wrangler pages project create my-app
wrangler pages deploy dist

# View deployments
wrangler pages deployment list

CF Pages’ build queue is the “build hook”: git push fires the build that runs prestruct. A wrangler pages deploy dist in CI is the equivalent for repos that build elsewhere.

Proxy commands

The bot proxy is opt-in and separate from the build. Commands, tied to what actually runs:

# VPS proxy (Node/Express/Puppeteer): needs scripts/proxy.js + the
# proxy.package.json dependency set (npm i in scripts/ first)
node scripts/proxy.js

# Same, under a process manager
pm2 start scripts/proxy.js --name prestruct

# Worker proxy (Browser Rendering + KV): scripts/proxy.worker.js + wrangler.toml
wrangler deploy

Both variants read config.proxy from ssr.config.js and share the x-prestruct-refresh cache-bust contract (auth: PRESTRUCT_SECRET). Details and the request flow: Proxy guide.

Common issues

Issue Fix
Command not found Check package.json scripts
Build fails Run npm run build with debug
Preview not working Check dist exists
prestruct: command not found Install the package locally (npm i -D prestruct) or run via npx
validate outputs nothing That means the config is fine; it prints errors only when something is wrong

Next steps