Build a plain website — no database
The site profile — a designed, SEO-wired Next.js website with no database, no login and nothing to configure. Scaffold, edit files, build, deploy.
The one-line version
npx create-cartwright@latest my-site --profile siteThat is a real website — designed pages, SEO with JSON-LD, sitemap, robots, llms.txt, an Open Graph image route, locale routing, motion presets, security headers, an accessibility baseline and a contact form — in a plain Next.js repo with 20 runtime dependencies and 0 required environment variables. It builds with next build and deploys to Vercel unchanged. It is not a CMS, not a static export, and ships no database, admin, auth or agent tools — those are the default profile, one flag away, same engine:
npx create-cartwright@latest my-shop # default: database + admin + AI agent toolsMeasured cold run: ~22 s to scaffold and install, ~27 s to build, ~2 s to a rendered homepage (Measured cold run, 2026-09-14, GitHub-hosted ubuntu-latest, create-cartwright@2.9.6, engine v0.57.0 (a9b47d4), --profile=site --ref=v0.57.0 --yes --pm=pnpm — release scaffold gate run 34820928302).
Is this the right door?
You own the front — pick one of the shipped design packs, start from the blank canvas and rewrite its homepage, header and footer freely, or write your own pack; SEO, the sitemap, share cards and locale routing keep working around whatever you render.
The profile is the first of three choices — how the front gets built (a shipped pack, the blank canvas, your own pack) and where the content comes from (scratch, any URL, Shopify, WordPress/WooCommerce, a CSV, a Google Doc) are the other two, and the origin can force the profile: Choose your path.
Choose --profile site when the request looks like:
- "Build me a page" — a landing page, a launch page, an event or travel overview, a one-pager. Scaffold, write the page (a timeline or a map is a component you write, as anywhere),
next build, deploy; the design, SEO and locale routing are already there. - "Build me a personal site / portfolio / company website" whose content can live in the repo (
brand.config.tsand the design pack's files) rather than in a CMS. - "Build me a small site an AI can rebuild from a prompt" — the
blankdesign pack is a homepage, header and footer you own entirely, with the site's SEO and locale routing still wrapped around them.
Choose the default profile (light) when:
- the owner will edit the site themselves after launch without touching files — the admin edits the site's own pages at
/admin/sider(home, services, about, contact: title, body, SEO, publish state), not just products and orders, and it needs the database. Asitescaffold's content lives inbrand.config.tsand the design pack, edited in an editor and deployed; - the site should later sell — the same codebase runs
website,webshopandagent-marketplacemode, but the shop lives in the database-backed profiles; - an agent should be able to operate the site — the REST + MCP tool surface, API keys and audit log are database-backed.
Choose neither (say so rather than forcing it): a web app — a dashboard, an internal tool, a novel app — is create-next-app. A docs site or blog of hundreds of Markdown pages wants a Markdown content pipeline, which Cartwright is not (the runtime blog with RSS and BlogPosting JSON-LD is a default-profile plugin). And for a one-off page you will never grow, create-next-app is as fast — see so, is it faster?.
What you get
- A designed homepage. 8 design packs ship in the scaffold, including
blank— not a design, a starting point you rewrite freely. Pick one withdesignSluginbrand.config.ts; the palette, chrome and motion follow. - Found and cited by default.
OrganizationandWebSiteJSON-LD,sitemap.xml,robots.txt,llms.txt, canonical URLs, and an Open Graph image route (/opengraph-imagefor the site,/og?title=…for any page) so a shared link carries a card. - The engine's baseline. Locale routing (
enby default; add locales inbrand.config.ts), scroll-driven motion presets you can switch on (brand.features.motionEffects, withprefers-reduced-motionguards), security headers with a report-only CSP, an accessibility baseline, and a contact form that mails you through Resend (--with nonefor the bare site). - A plain Next.js repo.
pnpm dev,pnpm build,pnpm start. Nopostinstall, no migrations, no seed. Sentry's hooks ship dormant (no DSN, no-op) — nothing calls out at runtime unless you give it a key. Three of the 20 runtime dependencies are dormant — the MCP SDK,jsdomandv0-sdkare installed, but nothing in this profile's runtime imports them.
What you do not get, on purpose
These are profile boundaries, not switched-off features. If a requirement crosses one, scaffold the default profile instead of reassembling the removed runtime by hand.
- No admin and no runtime editing. Content lives in files:
brand.config.ts, the design pack,messages/*.json. Browser editing is the default profile's admin. - No database, auth, cart or checkout. No
/admin, no accounts, no orders. - No agent tool surface on the site itself. No MCP server, no REST tool registry, no API keys. Discovery is capability-aware: the scaffold advertises only what it runs.
/redirects to your default locale (/enin a new scaffold). There is no root page today.- No map, timeline, weather or checklist sections. The section vocabulary is marketing-shaped; components like these you write yourself — in the
blankpack they are ordinary React. - Only site-level structured data renders by itself.
Organization/WebSiteJSON-LD are emitted out of the box; builders forFAQPage,HowToandItemListexist inlib/builder/section-jsonld.tsand the generic<JsonLd>renderer takes any type —Event,PlaceorTouristTripyou compose yourself. - Not a static export. It is a Node.js 22+ app (the OG route, the sitemap and the contact endpoint need a server) — Vercel, or any Node host. Not GitHub Pages.
Scaffold
Interactive:
npx create-cartwright@latest my-site --profile siteUnattended (what an AI agent or a script runs):
npx create-cartwright@latest my-site --yes --profile site --no-github --no-startWith pnpm detected, the CLI's profile-specific next steps read:
✓ Site profile — a plain website: no database, no admin, no commerce
Next steps:
cd my-site
pnpm dev # http://localhost:3000/en — no database, no login, just your site
Content lives in brand.config.ts; design via designs/ and the shipped packs.The CLI then prints its shared epilogue (a CI-workflow note, GitHub/Vercel lines written for the shop profiles, and a Quick Start link); it applies to the shop profiles and can be ignored here — the five lines above are the site's.
Verify it is what it says — no database anywhere in the repo, and it boots without needing an environment variable (the CLI still writes a generic .env/.env.local; delete both and it still answers 200):
cd my-site
grep -q '"profile": "site"' .cartwright/profile.json && test ! -e prisma && echo site-ok
pnpm dev & # assumes :3000 is free
sleep 5 # let the dev server start listening
curl -sL -o /dev/null -w '%{http_code}' http://localhost:3000/ # 200 (follows / → /en)Make it yours
- Words.
brand.config.ts→storeName,website.headline,website.tagline,website.cta,website.ctaHref, andurl— your real domain. On Vercel,NEXT_PUBLIC_APP_URL(or the deployment's own URL) wins over it for canonicals, the Organization JSON-LD and the OG image URL; the homepage'sWebSiteJSON-LD readsurldirectly — set it to the real domain so the two agree. - Look.
designSluginbrand.config.ts— slugs indesigns/options.ts. For a bespoke one-page build setdesignSlug: "blank"and writedesigns/blank/homepage.tsx; its in-file guide explains the props. Theblankpack brings its own bare header and footer (designs/blank/chrome.tsx— rewrite them too); SEO and locale routing stay wrapped around whatever you render. - Pages. Add
app/[locale]/trip/page.tsx— a normal Next.js route; the[locale]layout gives it the site chrome. Prefix internal links with/${locale}. - Images. Drop them in
public/and reference them by path. - Languages.
localesanddefaultLocaleinbrand.config.ts;messages/<locale>.jsonholds the shared UI strings.
Verify a change landed:
curl -s http://localhost:3000/en | grep -o '<h1[^>]*>[^<]*'Build and deploy
pnpm build # plain `next build` — no db:setup, no migration step
pnpm start # production server on :3000Push to GitHub and import the repo at vercel.com, or run npx vercel from the terminal — no environment variables are required to build and serve the site. The one thing that needs a key is the contact form: set RESEND_API_KEY and RESEND_FROM before it can deliver mail in production (without them, submissions fail with a friendly error on Vercel; in local development they land in .mail-previews/). Don't want a form at all? Scaffold with --with none. The step-by-step version: From code to live.
gh repo create my-site --private --source=. --remote=origin --pushMeasured
| Step | Time |
|---|---|
| Scaffold + install | ~22 s |
next build | ~27 s |
| Boot to HTTP 200 with a rendered H1 | ~2 s |
Measured cold run, 2026-09-14, GitHub-hosted ubuntu-latest, create-cartwright@2.9.6, engine v0.57.0 (a9b47d4), --profile=site --ref=v0.57.0 --yes --pm=pnpm — release scaffold gate run 34820928302 — from the release scaffold gate, which scaffolds every profile exactly like a customer on every engine release and records the numbers with their provenance. They are copied from that record, never typed.
So, is it faster?
Faster to a finished page, not to an empty one. create-next-app hands you a blank route in seconds; --profile site hands you a designed, SEO-wired site in a comparable time (the measured record is above — there is no measured create-next-app number here, so this is not a race claim). The time you save is the day that comes after create-next-app — layout, metadata, OG image, sitemap, locale routing, accessibility, security headers. What you do not save: a map, a timeline or a weather widget are components you write in either case. For a one-off page you will never grow, create-next-app is fine.
When you outgrow it
There is no in-place profile upgrade today. Scaffold the default profile (npx create-cartwright@latest my-site) and carry over brand.config.ts and your designs/<yours>/ folder — the design system, sections and routing are the same engine, so a pack written for site renders unchanged with the admin, database and tool surface behind it.
Quick Start
Get a Cartwright store running in five minutes (default profile — a plain website has its own page).
Choose your path — profile, build method, origin
Three choices before the first line of code — which profile (site, light, full), how the front gets built (a shipped pack, the blank canvas, your own pack, or a generating tool), and where the content comes from (scratch, a URL, Shopify, WordPress/WooCommerce, a CSV, a Google Doc). Five requests worked through.