Starter template for a NullJS application — serverless JavaScript/TypeScript functions (HTTP routes, cron jobs, event handlers) plus pages in React, Svelte, or Solid: server-side-rendered pages and an optional client-rendered SPA, running on the platform's pooled sandboxed runtimes.
Install the nulljs binary once (it contains the whole platform — CLI, server, and bundler):
curl -fsSL https://raw.githubusercontent.com/tothalex/nulljs-public/main/install.sh | shThen either scaffold a fresh project from this template:
nulljs create my-app && cd my-app
nulljs devor work in this repo directly:
pnpm install
pnpm dev # runs `nulljs dev`nulljs dev starts a full local stack — no bun, no node, no vite — and auto-deploys
everything on save, including the React SPA (the browser live-reloads after each deploy):
| What | Where |
|---|---|
| Dashboard (logs, invocations, secrets) | http://localhost:3000 |
| Your functions (gateway) | http://nulljs-template.localhost:3001 |
| React SPA | http://nulljs-template.localhost:3001/ |
Try the example route:
curl http://nulljs-template.localhost:3001/helloRename the app by changing name in package.json — it becomes the subdomain.
src/
function/
api/ HTTP routes — one file per route
cron/ scheduled functions
event/ event handlers (async messaging between functions)
page/ server-side-rendered React pages — one file per page (try /ssr)
index.tsx client-rendered SPA entry (React; or Solid when it imports solid-js;
Svelte SPAs use index.svelte instead); delete it if unneeded
lib/ shared code, bundled into functions that import it
test/cloud/ vitest aliases mapping cloud/* imports to in-memory test doubles
.secret local secrets (gitignored); copy .secret.example to get started
Every function file default-exports a config object with its handler — see the examples in
src/function/ and the full guide in AGENTS.md.
Pages under src/page/ are server-side rendered, in React, Svelte, or Solid: the
platform renders the page to HTML per request and hydrates it in the browser with the
same props. props(request) runs server-side with secrets and cloud/* access. The
template ships one of each — try them:
curl http://nulljs-template.localhost:3001/ssr?name=you (React),
/docs (Svelte), /board (Solid). Routing composes by specificity: API routes and
pages own their exact paths, the SPA catches the rest — see AGENTS.md's Routing
section.
Functions import server-provided modules instead of npm packages:
cloud/postgres (SQL), cloud/cache (KV store), cloud/got (HTTP client), cloud/secret
(secrets, JWT, password hashing), cloud/event (messaging), cloud/uuid. Typings ship in
@tothalex/cloud.
Note: the runtime is a sandboxed engine with a Node-compat subset — not Node.js. There is
no fs and no child_process.
cp .secret.example .secret # then edit values
nulljs secret deploy # push to the serverFunctions read secrets from process.env and can declare exactly which ones they need via the
secrets: [...] config field.
pnpm test # vitest against in-memory cloud/* doubles
nulljs deploy # deploy all functions to the selected environmentThis template is set up for coding agents: AGENTS.md (and its CLAUDE.md symlink) documents the
platform contract, and .claude/skills/ contains guides that Claude Code picks up automatically —
just ask for "a new cron job", "an API route", "an event handler", or database/cache/HTTP usage.