A small host for big little ideas

Ship the
whole idea.

Static pages, server functions, realtime data, secrets, and scheduled jobs. One folder. One command. No cloud archaeology.

Read the quickstart

Built for humans and the agents who code with them.

index.htmlyour interface
ask.jsserver function
refresh.jsscheduled job
LIVEidea.singlepageapp.co

Everything your small app actually needs

STATICFUNCTIONSREALTIME KVUSER DATACRONSECRETS
01 / THE PITCH

The good kind of boring

Your project is
just files.

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.

01

Save. See it live.

singlepage watch syncs every change. Open pages reload automatically; CSS swaps without losing state.

watching 3 directories
public/style.css synced 38ms
02
ƒ

Backend, minus backend ops.

Drop a JavaScript file into server/. It becomes a sandboxed endpoint with data, secrets, fetch, and response helpers built in.

03

Realtime by default.

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)
04

Users without user accounts.

Every visitor gets a private, signed identity and personal KV store. Perfect for carts, drafts, preferences, and one-vote rules.

05

Agent native.

singlepage init installs a complete project guide for coding agents. They know the platform before writing the first line.

AI context included
02 / QUICKSTART

From empty folder to URL

Three commands.
That’s the stack.

Single Page scaffolds the project, gives it a live subdomain, and keeps your local files in sync.

01

Make a home

mkdir my-idea && cd my-idea

Start with an empty directory. No starter repository or framework required.

02

Initialize

singlepage init

Creates your site, project folders, credentials, and coding-agent instructions.

03

Go live

singlepage watch

Uploads the site and watches for changes. Your printed URL is live immediately.

03 / DOCUMENTATION

The model

Small surface.
Full stack.

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.

BROWSERpublic/kv · fn · user
SINGLE PAGErealtime + routingisolated runtime
YOUR CODEserver/cron/ · .env

PROJECT LAYOUT

Everything has a place

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

Start with the web

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.

public/index.html
<script type="module">
  import { kv, fn, user } from "/__inject.js";
</script>

SERVER FUNCTIONS

An endpoint is one file

Default-export a handler from server/<name>.js. It is available at /__fn/<name> and through the injected fn helper.

server/greet.js
export default (req, ctx) => {
  return ctx.json({ hello: req.query.name ?? "world" });
};
Sandboxed by design

Functions cannot access the host filesystem or process. Outbound fetch blocks private and loopback addresses. Each invocation runs with memory and time limits.

Request and context

req.methodHTTP method
req.queryQuery parameters
req.headersRequest headers
req.bodyRaw body string
ctx.kvFull data access
ctx.userVerified visitor
ctx.envSite secrets
ctx.fetch()Safe outbound fetch

SHARED DATA

JSON with a live wire

The per-site KV store is available in the browser and backend. Browser subscriptions are filtered server-side and delivered over WebSocket.

public/app.js
import { kv } from "/__inject.js";

await kv.set("count", 1);
const count = await kv.get("count");
kv.on("count", ({ value }) => render(value));

Visibility classes

ClassBrowser readBrowser write
privateNoNo
readonlyYesNo
readwriteYesYes

Classes are backend-owned. Never put a secret in a readonly or readwrite key.

PER-USER DATA

Identity, no login screen

Every visitor receives a stable anonymous identity in a signed HttpOnly cookie. user.kv is private and automatically scoped to that visitor.

public/cart.js
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

Keep private things private

Put site API keys in the project-root .env. They sync outside the public directory and appear only to backend code through ctx.env.

.env
OPENAI_API_KEY=sk-...
server/ask.js
const key = ctx.env.OPENAI_API_KEY;

CRON JOBS

Put recurring work on a clock

Files in cron/ use the same handler and context as server functions. Schedule them by name in singlepage.json.

singlepage.json
{
  "cron": {
    "refresh": "0 * * * *"
  }
}

CLI REFERENCE

Four commands, on purpose

singlepage init

Create a site and scaffold a complete project.

singlepage watch

Deploy once, then sync local changes continuously.

singlepage rotate-key

Issue a new site-scoped deploy key.

singlepage regen-docs

Refresh the coding-agent guide after a CLI upgrade.

Choose the simple thing

Build the page.
Keep the momentum.

The web is already a great application platform. Single Page just gives it the missing pieces.

Get started
Copied to clipboard