Documentation
Docs
Introduction
Getting Started
Tutorial: build an app
Core Concepts
Routing
Server-Side Rendering
Mimir, state management
Pages & Layouts
API Routes
Styling & Theming
Building & Deploying
API Reference
Guides
Recipes
FAQ (use cases)
The application
Everything starts with createApp. It returns an application object you register routes and middleware
on, then start. This page is the reference for that object and the options it takes.
createApp(options)
| Option | Type | Default | Purpose |
|---|---|---|---|
port | number | 3000 | Listening port. |
host | string | "0.0.0.0" | Bind address. Pair with a firewall/nginx in prod (see deploy). |
manifest | object | null | The build manifest from readManifest(); lets the server emit the right client <script>/modulepreload tags. |
layouts | object | null | The layout tree (root + nested). See Layouts. |
notFound | Component | null | The 404 component, rendered for unmatched routes. |
error | Component | null | The error component for render failures. |
ssr | "eager" | "background" | "lazy" | "eager" | Default SSR strategy for static, SSR-enabled routes. See Strategies. |
lang | string | "en" | <html lang>. |
static | string | – | A directory served verbatim. |
staticPrefix | string | "/static" | URL prefix for static. The examples use /assets. |
tls, http2 | – | – | Passed to the underlying server (usually you terminate TLS at nginx instead). |
maxBodySize, maxWsMessageSize | number | – | Request/WebSocket size limits. |
seo | object | – | Carried for convenience; SEO tags are produced via createSEO(...).headTags() and injected through page head. |
Methods on the app object
app.page(path, component, meta?)
Registers a route. component is the page module (it may be the module namespace with a default export
and optional ssr, or the component directly). meta carries:
page, the page key into the manifest (e.g."index.tsx"), so the server knows which client chunk to load.title, a default document title.head, extra HTML for<head>(compiled CSS, SEO tags, no-FOUC script).ssr, a per-route strategy override ("eager" | "background" | "lazy").ttl,tags, SSR cache controls (see Caching).guard, a client redirect rule.
Returns app for chaining.
app.pages(dir, components, metas)
A bulk helper: scanRoutes(dir) + register each discovered route whose pattern/file you provide a component
for. Most apps loop over scanRoutes themselves (it is more explicit); pages() is the shorthand.
app.api(method, path, [opts], handler)
Registers an API route. method is "GET" | "POST" | "PUT" | "DELETE" | "PATCH". The handler gets
(req, res); returning a value auto-sends it (objects as JSON, else as text). See
API routes.
app.use(middleware)
Adds middleware to the underlying server (runs for every request). See Middleware.
app.layout(fn)
Sets a single root layout function (the layouts option is the richer, tree-based form).
app.invalidate(pathOrTag)
Drops cached SSR HTML and re-renders. "*" clears everything; a path ("/blog") targets one route; any
other string is treated as a tag and clears every cached page carrying it. See
Caching & invalidation.
app.start()
Begins listening and returns { server, url, stop, invalidate, cache }. On start it:
- Mounts static serving for the client bundle at
/_ekko(from.ekko/build/client, long-cache + immutable). - Opens the HMR WebSocket at
/__ekko_hmrand starts watching the build token. - Registers your API routes (with automatic
405 Method Not Allowedfor declared paths). - Builds the client route table (
__routes) and finds the shared layout chunk for hydration. - Registers a GET handler per page, cached SSR for static SSR routes, a shell for the rest.
- Registers the
notFoundcatch-all and anystaticdirectory. - Eagerly renders the eager SSR routes into the cache, then prints the listening URL.
- Schedules background SSR routes to render just after start.
A minimal but complete entry
Next: what actually happens on a request, The rendering pipeline.