Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Voice Edit Studio (talk-to-code) is a voice-controlled workspace for
building and editing Val Town vals just by talking. You see
a val's live page in an iframe on the left and speak to an AI host (powered by
the OpenAI Realtime API) that reads, writes, and creates vals for you in real
time.
Live at talk.val.run.
- Talk to edit — describe a change ("add a dark mode toggle", "make the header bigger") and the AI edits the val's files, then reloads the preview.
- Open any val — say "open my X", type a val name in the box (a bare
name resolves to your handle;
handle/nameand pasted val.town URLs work too), click one from Recent vals, or seed it with?val=handle/name. - Create from scratch — the ✨ Create a new val button (or just asking the AI) spins up a minimal HTTP val with a starter page and loads it, so you have an instant canvas to iterate on.
- Newcomer-friendly — the AI is briefed to assume the person may be brand new to this and to Val Town, orient them in plain language, and offer a concrete first thing to build.
- Scenes & choreography — vals can ship a
CHOREOGRAPHY.md; the AI triggers pre-built overlays via theset_scenetool and can drive slideshows.
- The browser logs in with Val Town OAuth and opens a WebRTC mic connection.
POST /rtcnegotiates an OpenAI Realtime session, seeded with the official Townie system prompt plus a Studio-specific addendum, and attaches the signed-in user's Val Town MCP token so the AI can read/write their vals (routes/agent.ts).- The AI calls function tools handled in the browser —
load_val,navigate_page,reload_site,set_scene,slide_next/prev/goto— and theval_town_mcptools for file edits. - The preview iframe reloads on demand (via the
reload_sitetool or the "↻ Reload site" button) — auto-refresh polling is intentionally disabled.
The deployed studio runs on the owner's OPENAI_API_KEY. If that key is ever
rejected or out of quota, the UI shows a "remix this val & add your own
OPENAI_API_KEY" prompt instead of a cryptic error.
To run your own copy:
- Remix this val (the link in the error, or the Remix button on the val page).
- Set
OPENAI_API_KEY(an OpenAI key with Realtime API access) in the remixed val's environment variable settings. - Open the val's HTTP endpoint and start talking.
OPENAI_API_KEY(required) — OpenAI key with Realtime API access. The app no longer crashes at startup when this is missing; instead/rtcreturns a structured error the UI turns into the remix prompt above.
GET /— serves the studio (frontend/studio.html)POST /rtc?val=<handle/name>— create a new WebRTC Realtime session (valis optional). Returns{ code: "openai" | "upstream", ... }on failure.POST /observer/:callId— internal server-side session control (fire-and-forget)GET /me— current login stateGET /auth/token— OAuth token handoff (rarely needed; the studio is same-origin)GET /source— 302-redirects to this val's page on Val Town (used by the remix link, so it's correct even for remixed copies)GET /api/resolve-val?val=<handle/name>— resolve a val to its live HTTP URLGET /api/recent-vals— the signed-in user's most recent valsPOST /api/create-val— create a new public val with a minimal HTTP starter
├── main.tsx # Entrypoint: OAuth middleware, route mounting, /me, /source, serves studio
├── frontend/
│ └── studio.html # The Voice Edit Studio UI (WebRTC, waveform, sidebar, load/create)
└── routes/
├── agent.ts # Realtime session config: tools + Townie prompt + Studio addendum
├── rtc.ts # WebRTC session setup + OpenAI-error classification
├── observer.ts # Server-side session control (WebSocket to OpenAI)
├── api.ts # /api: resolve-val, recent-vals, create-val
└── utils.ts # Realtime API URL/header helpers + hasOpenAIKey()
Other files (routes/sip.ts, frontend/index.html, frontend/widget.html,
frontend/sdk.js, sdk.ts, oauth-test.tsx) are inherited from the
hello-realtime base this was built on and are not mounted by main.tsx.
- If the AI says it can't edit files, the Val Town OAuth token has gone stale — log out and back in from the sidebar to refresh it.
- The preview does not auto-refresh — the AI reloads it after finishing edits, or you can hit "↻ Reload site".