How a MicroHost site works
A MicroHost site is a release: an immutable set of files. Visitors get files from its public/ directory. Requests that match a script route run a JavaScript handler from the same release, inside a sandboxed engine, with only the capabilities an administrator granted. Persistent data (the SQLite database and private storage) lives outside the release, so deploying new code does not replace data.
Request lifecycle
- Edge. The HTTP listener checks the request line and headers (16 KiB), the request target (8 KiB), the path syntax, and a per-client-IP rate limit (60 requests per 60 s by default). It picks a site by the
Hostheader. Admin and preview hostnames never reach site code. Any path whose first segment is_admin(in any letter case, also percent-encoded) gets a generic 404. Dot-files andmicrohost.jsonare never served. - Site and release. The host maps to a site and its active release. An unknown host gets a generic 404.
- Routing. The router decides between a script and a static file, in this order: exact manifest route, real static file in
public/, patterned manifest route,/api/<name>convention route, then the not-found handling (404.html, otherwise a generic 404). Details and the method rules are in Routing. - Static response. A static file is read from the release's
public/directory and served withETag,Cache-Control, conditional requests and byte ranges. No script runs. - Script response. For a script route the host applies the site's request rate limit (default 60 per 60 s, answered with 429), buffers the request body (at most 1 MiB), and creates an execution lease with the site's limits and grants. The lease is bound to the engine chosen by the site policy: QuickJS in Wasm (the default), a native in-process QuickJS (trusted sites only), or a QuickJS worker process in a Linux sandbox.
- Engine. The engine starts a fresh JavaScript runtime, installs the SDK globals, loads your entry module and its static imports, and calls
default(request, ctx).ctxcontains only the capabilities that are both requested by the release and granted by policy. Every call to the database, storage, secrets, mail or network goes through a host broker that re-checks the grant and the budgets on each call. - Response. The handler's
Responseis validated: status 200 to 599, legal header names and values, no hop-by-hop headers, nocontent-length, body within the response limit. Anything else becomes a sanitized error. Visitors see only generic texts (Internal Server Error,Bad Gateway,Gateway Timeout,Forbidden). Details go to the operator log. See Limits and errors.
There is no shared state between executions. Module variables do not survive a request. There are no timers, no background work and no waitUntil: await everything you need before you return.
Static versus scripted
| Static | Scripted | |
|---|---|---|
| Lives in | public/ |
api/, lib/ and any other path outside public/ |
| Served by | The host's file server | A JavaScript handler in an engine |
| Reachable by URL | Yes: public/styles.css is /styles.css |
Only through a route: an explicit microhost.json route or /api/<name> |
| Runs in | The visitor's browser (if it is browser JavaScript) | QuickJS with the Handler API and ctx |
| Can use the database | No | Yes, with the database grant |
Browser JavaScript in public/app.js has the DOM and fetch of the browser. Server handlers have neither; they get the smaller, explicit surface documented in the Handler API. MicroHost does not run JavaScript embedded in HTML on the server, and it does not run TypeScript, PHP or Python. Compile TypeScript to JavaScript before you deploy.
Releases, grants and the manifest
- Release. Every ZIP upload, Git deploy and editor publish creates a new immutable release. A deploy can stage the release (
activate=false) or activate it in the same call; activating switches the site to it. Rolling back is activating an older ready release. See Deploying. - Manifest. On every deploy the server builds a resolved manifest for the release from
microhost.config.js, otherwisemicrohost.json, otherwise defaults. It states what the release requests: routes, SDK modules, permissions, limits, admin extensions. See Manifest and Config script. - Grants. A request is not a grant. An administrator grants capabilities per site, and the effective access is the intersection of what the release requests, what policy grants, and what resources are available. A grant change applies to the next broker call, including during a running execution; no redeploy is needed.
- Migrations. SQL files in
private/migrations/shape your database. See Migrations.
What the SDK adds
Your handler always has Request, Response, Headers, URL, TextEncoder, TextDecoder, crypto.getRandomValues, console and (when granted) ctx.db, ctx.storage, ctx.env, ctx.mail and fetch. On top of that the SDK provides four optional modules that you import explicitly: microhost/sql, microhost/db, microhost/auth, microhost/session. They are loaded lazily, so a handler that does not import them pays nothing. See SDK modules.
Next
Quickstart builds the smallest site and then a site with a database.