Skip to content
runlot

Project structure

A project is made up of the runlot.json config file, a worker entry point, and a static assets directory.

create-runlot generates the following default project structure.

my-app/
  runlot.json      project config
  src/index.ts     worker entry point
  public/          static assets
    hello.txt
  .gitignore

runlot.json

runlot.json
{
  "name": "my-app",
  "org": "me",
  "main": "src/index.ts",
  "assets": "public"
}

name is required. You also have to set at least one of main or assets — without either there is no worker code or static asset to serve. See the runlot.json reference for the full list of fields.

Every project comes with a database, login, file storage, email and AI, so runlot.json does not list them. Turning one off is an explicit command such as runlot storage delete, and runlot storage on brings it back.

Entry point

Implement a fetch method on the object you export default. It receives the request and the environment, and returns a Response.

src/index.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    return new Response("hello runlot");
  },
};

The worker reaches the features you've enabled through env. env.assets is always available, and depending on which features you added you can use env.db, env.storage, and env.auth. Secrets are exposed under uppercase names, so they never collide with the lowercase binding names.

Static assets

Every file in the directory assets points to is included in the bundle, and the worker serves it through env.assets.

if (url.pathname.startsWith("/static/")) {
  return env.assets.fetch(
    new Request(new URL(url.pathname.slice("/static".length), url), request),
  );
}

Specify only assets without main and the project deploys as a static site. In that case an entry point that forwards every request to the static assets is generated for you.

Only real files go into the bundle. Symbolic links and paths that point outside the project root are not allowed, because allowing them could end up serving unintended files from the node.

Migrations directory

By default, runlot pg migrate applies the files in the migrations/ directory.

my-app/
  migrations/
    0001_init.sql
    0002_posts.sql

See Migrations for details.

On this page