Skip to content

Working on Workers

This page is for contributors working on Lombok’s worker runtime — the code in packages/core-worker that executes background and app work.

It covers where worker code lives, how the worker runtime fits into Lombok’s boundaries, and how to run the relevant checks locally. It does not repeat environment setup — for that, start with Local Development with dx.

Two different kinds of “worker work.” Contributing to the worker runtime (this page) is different from authoring an app’s workers as part of building a Lombok app. If you are writing workers for an app, skip to Building app workers vs. working on the runtime.

Lombok is a Bun workspace monorepo, so worker work is not in a single src/ folder. The main anchors are:

  • packages/core-worker — the worker runtime
  • packages/worker-utils — utilities used in worker and processing contexts, especially media/file processing such as image and video handling

Per the Package Map, packages/core-worker is responsible for:

  • core worker execution
  • app worker execution
  • sandboxed worker-task execution paths
  • background processing and analysis flows

When deciding where to look first, the Repository Conventions routing guide is direct: worker execution and background processing → packages/core-worker.

The worker runtime is one side of one of Lombok’s most important boundaries. As described in Runtime Boundaries:

  • the API decides what work should run
  • the worker runtime executes the underlying worker logic

This split exists so app/runtime work is not treated as ordinary inline API logic. Two further boundaries matter when working on the runtime:

  • Worker runtime ↔ sandboxed execution. The core worker runtime coordinates work, but worker execution happens inside a sandboxed worker environment. The architecture docs specifically flag the nsjail-sandboxed worker daemon model as a key trust and isolation seam.
  • Task dispatch transport. Lombok’s documented mental model uses a DB-backed task table and Socket.io room-based dispatch between the API and the worker-side execution model — there is no assumed external Redis/BullMQ/RabbitMQ queue.

Keep these boundaries in mind: changes in packages/core-worker sit downstream of the API’s task decisions and upstream of sandboxed execution.

The worker runtime does not start a flow on its own. Following the App Execution Lifecycle, the usual path is:

  1. a core event occurs or a schedule matches
  2. a trigger selects a task
  3. the task resolves to a handler
  4. the handler points to a runtime worker
  5. Lombok executes that worker through the worker runtime

The runtime-worker path is the primary execution model. Lombok also supports Docker-backed handler paths, but the architecture docs treat those as a distinct secondary mode rather than the default — see Architecture Overview.

Worker development uses the same Docker-based local loop as the rest of the repository, driven by the ./dx developer CLI. The full setup — prerequisites, ./dx up, and the /etc/hosts entry — is documented in Local Development with dx; this page does not duplicate it.

To follow logs from the running environment:

Terminal window
./dx logs

For the full list of ./dx commands, including service reload/restart options, run:

Terminal window
./dx help

Use ./dx for the standard contributor checks. Linting, formatting, and type-checking are shared across the monorepo:

Terminal window
./dx check all
./dx check eslint
./dx check prettier
./dx check tsc

Run unit tests for the worker package, and the worker end-to-end suite, with:

Terminal window
./dx unit core-worker
./dx e2e core-worker

Refer to Local Development with dx for how these commands fit into the wider workflow. Dedicated pages for tests and linting/type-checking are planned for this docs wave.

Building app workers vs. working on the runtime

Section titled “Building app workers vs. working on the runtime”

These are two different surfaces, and it is worth being explicit about which one you are on:

  • Working on the worker runtime (this page) means changing how Lombok executes workers — code in packages/core-worker and helpers in packages/worker-utils.
  • Building app workers means writing the workers an app declares and ships, which run on top of the runtime. That is app-platform development, not runtime development.

If you are building app workers, the relevant docs are:

  • Workers — how runtime workers are declared in an app’s config.json manifest under runtimeWorkers, and the event → trigger → task → worker flow
  • App Worker SDK — the @lombokapp/app-worker-sdk code surface those workers use at execution time
  • Events & Tasks and App Configuration — the surrounding manifest and orchestration model

The connecting idea, from the lifecycle docs: the manifest says what can run, and the worker runtime is what actually runs it. App authors work on the former; runtime contributors work on the latter.

When deciding where a worker-related change belongs:

  • how work is executed, coordinated, or sandboxed → packages/core-worker
  • media/file processing helpers used during worker execution → packages/worker-utils
  • what an app declares and the code it runs as a worker → the app-platform surface and App Worker SDK, not packages/core-worker
  • deciding whether work should run, or dispatching it → the API/control plane in packages/api

Lombok is organized by runtime responsibility rather than by a single app folder, so matching your change to the right package keeps the boundaries clean.