A marketing site + blog in 5 minutes, no build step

Start state: nothing. End state: a live marketing site with a blog — plain HTML + JS + vanilla CSS (BEM), no framework, no install, no build step. Edit JSON, regenerate, deploy files as-is.

1. Scaffold

pnpm new my-launch --title "My Launch" --type website-blog --stack static --accent teal

Expected output ends with:

Next steps:
  open apps/my-launch/index.html            # it's just files — no install, no build
  pnpm deploy my-launch                     # → Cloudflare Pages
  pnpm regen-blog my-launch                 # after editing content/blog.json

Open apps/my-launch/index.html in a browser right now — it already works. You get index.html + css/ + js/, a generated blog/ with an index and post pages, the editable content/blog.json source, and an llms.txt machine-readable site summary. (--design belongs to the react stack; static sites are themed via --accent + --mode.)

2. Write a post

Add an object to the array in apps/my-launch/content/blog.json. A post is slug, title, date, tags, excerpt, and body blocks (p, h2, quote, code, list):

{
  "slug": "were-live",
  "title": "We're live",
  "date": "2026-07-20",
  "tags": ["announcement"],
  "excerpt": "My Launch is out — here's what it does and what's next.",
  "body": [
    { "kind": "p", "text": "Today we're launching My Launch to everyone." },
    { "kind": "h2", "text": "What's in v1" },
    { "kind": "list", "items": ["The core product", "A public roadmap", "This blog"] },
    { "kind": "quote", "text": "Ship early, write it down." }
  ]
}
Text is HTML-escaped by the generator — write plain text in every block, not HTML.

3. Regenerate

pnpm regen-blog my-launch

Expected: blog/were-live.html appears and blog/index.html lists the new post first. Refresh the browser — no server restart, because there is no server.

4. Customize the look

All theming is CSS custom properties at the top of apps/my-launch/css/site.css — colors, radius, fonts. Change the tokens, refresh. The --accent and --mode you chose at scaffold time are just the initial values of these same variables.

5. Deploy

pnpm deploy my-launch --to surge     # fastest demo: https://<name>.surge.sh in seconds
pnpm deploy my-launch                # or the default: Cloudflare Pages

Static sites deploy their files as-is — no build phase at all. Any of the 6 providers works (cloudflare, vercel, netlify, surge, heroku, github-pages); login flows launch automatically, and the choice is remembered in apps/my-launch/.deploy.json.

What you built

  • A live marketing site + blog with zero runtime dependencies, versioned entirely in git
  • A publishing loop: edit content/blog.json → pnpm regen-blog my-launch → pnpm deploy my-launch
  • A theming surface that is just CSS variables in one file