The public Cloudhal playground: every visitor gets their own disposable Cloudhal (Studio, API and the rendered site) with no account. A session lasts an hour after its last request, two hours at most, and Reset starts over at once.
The design is RFC-0036
and ADR-0038
in the Cloudhal monorepo. This repo only composes the
published @cloudhal/* packages; the playground code itself is @cloudhal/cloudflare/playground.
- One Worker,
cloudhal-playground, built byastro buildfrom this repo: the entry issrc/playground/worker.ts(wrangler.jsoncmain), bundled with the blog theme (src/pages,src/layouts,src/components,src/styles: the@cloudhal/cliblog starter). - One SQLite-backed Durable Object per session (
PlaygroundSite): the store, the API in playground mode and the site renderer for that visitor. Seeded on first use with the demo pack (src/playground/demo-pack.ts). - Static files (
dist/client): the landing page is rendered by the Worker; Studio is copied from@cloudhal/cliat build time (scripts/copy-studio.mjs) and served at the root; the theme's assets; the demo images underpublic/demo/(generated byscripts/demo-media.mjs), read-only beneath each session's own blobs. /s/<session>/…is the visitor's site, private (no-store,noindex)./api/*is guarded byisBlockedInPlayground: no sign-in, people, keys, MCP, uploads, outbound calls, schedules or AI.
Needs Node 24 and pnpm 12.
pnpm install
cp .env.example .dev.vars # then set PLAYGROUND_SECRET (openssl rand -hex 32)
pnpm dev # build + wrangler dev → http://localhost:8787
pnpm check # Biome + TypeScript| Name | Kind | Purpose |
|---|---|---|
PLAYGROUND |
Durable Object (PlaygroundSite, new_sqlite_classes) |
one database per session, and the daily counter |
SESSION_LIMIT, WRITE_LIMIT |
rate limits | 5 new sessions / min per IP, 120 writes / min per session |
PLAYGROUND_ENABLED |
var | kill switch; only "true" opens the playground (ships "false") |
PLAYGROUND_DAILY_SESSIONS |
var | new sessions per UTC day |
PLAYGROUND_SECRET |
secret | signs the __Host-cloudhal_try cookie (≥ 32 chars); without it, landing page only |
TURNSTILE_SECRET, TURNSTILE_SITE_KEY |
secret, var | Turnstile after a rate-limit hit (optional) |
pnpm exec wrangler secret put PLAYGROUND_SECRET # once
pnpm run deploy # build + wrangler deployOpen it by setting PLAYGROUND_ENABLED to "true" (wrangler.jsonc or the dashboard). The custom
domain is the commented routes entry in wrangler.jsonc (try.cloudhal.com, ADR-0037).
See CONTRIBUTING.md. Apache-2.0, see LICENSE. The theme files come
from the Cloudhal blog starter (Apache-2.0); the fonts under public/fonts/ carry their OFL
licences.