Save. See it live.
singlepage watch syncs every change. Open pages reload automatically; CSS swaps without losing state.
↳ public/style.css synced 38ms
A small host for big little ideas
Static pages, server functions, realtime data, secrets, and scheduled jobs. One folder. One command. No cloud archaeology.
Built for humans and the agents who code with them.
Everything your small app actually needs
The good kind of boring
Single Page removes the ceremony between a working idea and a live URL. No framework contract, build pipeline, database provisioning, or dashboard maze. Use the web platform. Add backend power only where you need it.
singlepage watch syncs every change. Open pages reload automatically; CSS swaps without losing state.
Drop a JavaScript file into server/. It becomes a sandboxed endpoint with data, secrets, fetch, and response helpers built in.
Store JSON and subscribe to changes. Build counters, live boards, chat, presence, and shared state without configuring a database or socket server.
kv.on("score", render)Every visitor gets a private, signed identity and personal KV store. Perfect for carts, drafts, preferences, and one-vote rules.
singlepage init installs a complete project guide for coding agents. They know the platform before writing the first line.
From empty folder to URL
Single Page scaffolds the project, gives it a live subdomain, and keeps your local files in sync.
mkdir my-idea && cd my-ideaStart with an empty directory. No starter repository or framework required.
singlepage initCreates your site, project folders, credentials, and coding-agent instructions.
singlepage watchUploads the site and watches for changes. Your printed URL is live immediately.
The model
A Single Page site is a folder deployed to its own subdomain. The browser gets static assets plus a tiny injected client. Server functions and cron jobs run in isolated sandboxes with access to your site’s data and secrets.
PROJECT LAYOUT
The scaffold is intentionally plain. Only these project paths are deployed.
my-idea/
├── public/ Static files served at the site root
│ └── index.html
├── server/ One JavaScript file per endpoint
├── cron/ Scheduled sandboxed jobs
├── .env Backend-only site secrets
└── singlepage.json Site config and cron schedules
STATIC PAGES
Anything in public/ is served at the site root. Every HTML page automatically has access to the injected ES module. Import only what you use.
<script type="module">
import { kv, fn, user } from "/__inject.js";
</script>SERVER FUNCTIONS
Default-export a handler from server/<name>.js. It is available at /__fn/<name> and through the injected fn helper.
export default (req, ctx) => {
return ctx.json({ hello: req.query.name ?? "world" });
};Functions cannot access the host filesystem or process. Outbound fetch blocks private and loopback addresses. Each invocation runs with memory and time limits.
req.methodHTTP methodreq.queryQuery parametersreq.headersRequest headersreq.bodyRaw body stringctx.kvFull data accessctx.userVerified visitorctx.envSite secretsctx.fetch()Safe outbound fetchSHARED DATA
The per-site KV store is available in the browser and backend. Browser subscriptions are filtered server-side and delivered over WebSocket.
import { kv } from "/__inject.js";
await kv.set("count", 1);
const count = await kv.get("count");
kv.on("count", ({ value }) => render(value));privateNoNoreadonlyYesNoreadwriteYesYesClasses are backend-owned. Never put a secret in a readonly or readwrite key.
PER-USER DATA
Every visitor receives a stable anonymous identity in a signed HttpOnly cookie. user.kv is private and automatically scoped to that visitor.
import { user } from "/__inject.js";
await user.kv.set("cart", items);
const cart = await user.kv.get("cart");Server functions see the same verified visitor as ctx.user, allowing rules such as one vote per visitor to be enforced on the backend.
SECRETS
Put site API keys in the project-root .env. They sync outside the public directory and appear only to backend code through ctx.env.
OPENAI_API_KEY=sk-...const key = ctx.env.OPENAI_API_KEY;CRON JOBS
Files in cron/ use the same handler and context as server functions. Schedule them by name in singlepage.json.
{
"cron": {
"refresh": "0 * * * *"
}
}CLI REFERENCE
singlepage initCreate a site and scaffold a complete project.
singlepage watchDeploy once, then sync local changes continuously.
singlepage rotate-keyIssue a new site-scoped deploy key.
singlepage regen-docsRefresh the coding-agent guide after a CLI upgrade.
Choose the simple thing
The web is already a great application platform. Single Page just gives it the missing pieces.
Get started →