← TinyGPT · docs · devlog · roadmap · speedup
source: docs/deploy.md · view on GitHub ↗

Deploying the playground

The browser app in browser/ is a Vite static build — no server, no API. It loads a pre-compiled WASM module from browser/public/, so the deploy environment does not need Emscripten; it only needs Node to run vite build.

Target: tinygpt.sarthakagrawal.dev, on Cloudflare Pages.

⚠ Deploy-gating prerequisite — the WASM artifacts must be in the repo at build time

browser/public/tinygpt.js, tinygpt.wasm, tinygpt64.js, and tinygpt64.wasm are produced by Emscripten (bash wasm/build_wasm.sh + bash wasm/build_wasm64.sh) and are listed in .gitignore by default. Cloudflare Pages does a fresh git clone + npm run build; if these files aren’t in the cloned tree, the production site 404s on them and the playground fails to initialize.

Three resolutions, ranked:

  1. Commit the artifacts (recommended). They’re small (~80 KB each, ~230 KB total) and change rarely (only when the C++ kernels change). One-shot fix:

    git add -f browser/public/tinygpt.js browser/public/tinygpt.wasm \
               browser/public/tinygpt64.js browser/public/tinygpt64.wasm
    git commit -m "deploy: commit the compiled WASM artifacts"

    The -f overrides the .gitignore entries. Then on every C++ change, rebuild and commit the new artifacts as part of the same commit.

  2. Install Emscripten in Pages build environment. CF Pages allows custom build commands; you’d npm install && bash wasm/install_emsdk.sh && bash wasm/build_wasm.sh && bash wasm/build_wasm64.sh && npm run build. Multiplies build time by ~3-5× and the emsdk install is finicky in CI. Not recommended unless option 1 becomes painful.

  3. Pre-built artifacts uploaded out-of-band to R2 or similar, then a build-time fetch step. Most complex; only worth it if the WASM grows past 1 MB and git becomes a real burden.

Deploying — current state and how it actually works

Heads-up. The tinygpt Pages project is currently set up as a direct-upload project (Git Provider: No in wrangler pages project list). That means every git push to GitHub does nothing for the live site — deploys need an explicit wrangler pages deploy.

Manual deploy (current path)

cd browser
npm run build
npx wrangler pages deploy dist --project-name=tinygpt --commit-dirty=true

That uploads dist/ to the production environment. Output ends with ✨ Deployment complete! Take a peek over at https://<hash>.tinygpt.pages.dev and the canonical tinygpt.sarthakagrawal.dev updates immediately (CF Pages does no edge caching on must-revalidate files; HTML and assets are re-fetched on every request).

If you want every git push to auto-deploy, connect Git provider in the Cloudflare dashboard:

  1. Workers & Pages → tinygpt → Settings → Builds & deployments → Connect to Git
  2. Select sarthak-fleet/tinygpt.
  3. Build configuration:
    • Production branch: main
    • Framework preset: None (Astro auto-detected; Vite isn’t in the preset list)
    • Root directory: browser
    • Build command: npm install && npm run build
    • Build output directory: dist
  4. Environment variables: none required.
  5. Save. Next push triggers an auto-deploy.

Cloudflare clones the whole repo, cds into browser/, installs dependencies and builds. First build is ~1 minute; subsequent builds are cached.

Possible gotcha with the auto-deploy: the docs library at /docs/<slug> imports markdown from ../../../../docs/*.md, which crosses the Astro src/ boundary. This is allowed by vite.fs.allow: [".."] in astro.config.mjs and works locally and via direct upload — but if CF Pages’ Vite/Node version disagrees, the build will fail. If that happens, copy docs/*.md into browser/src/content/docs/ and update the .astro wrappers to import from the new path.

Custom domain

After the first successful deploy:

  1. In the Pages project: Custom domains → Set up a custom domain.

  2. Add tinygpt.sarthakagrawal.dev. CF Pages will then sit in Verifying state and show you a CNAME to add.

  3. Add the CNAME manually, even though sarthakagrawal.dev is on the same Cloudflare account. The “added automatically” claim that used to live in this section was wrong — auto-CNAME only happens when you set up the custom domain at the same time as the Pages project, via the create-app flow. Adding a custom domain post-deploy requires the DNS record manually:

    • Zone: sarthakagrawal.dev → DNS → Records → Add record
    • Type: CNAME
    • Name: tinygpt (just the subdomain, not the full hostname)
    • Target: the value CF Pages shows (e.g. tinygpt.pages.dev)
    • Proxy: orange-cloud Proxied
    • TTL: Auto
  4. Back in Pages → Custom domains, click Check DNS records. It flips to Active in 30–60 s. SSL is then automatic.

After a minute or two: https://tinygpt.sarthakagrawal.dev.

What ships

The Vite build produces five HTML entry points (all listed in browser/vite.config.ts → build.rollupOptions.input; any HTML file not in that list is silently dropped from the production build):

The deployed assets total around 600 KB (WASM + JS chunks).

After deploy — update the case study

The TinyGPT case study on the portfolio (sarthak-fleet/portfolio: src/content/work/tinygpt.mdx) has repo: set but demo: deliberately omitted until the URL is live. Add:

demo: 'https://tinygpt.sarthakagrawal.dev'

and the case-study header will render a live demo ↗ link.

Local sanity check before deploy

cd browser
npm install
npm run build      # produces browser/dist/
npm run preview    # serves dist/ on http://localhost:4173

If npm run e2e passes (which it does on main), the production build will behave the same — the e2e drives the built bundle, not the dev server.