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.
Where worker code lives
Section titled “Where worker code lives”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 runtimepackages/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.
How the worker runtime fits in
Section titled “How the worker runtime fits in”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.
How work reaches a worker
Section titled “How work reaches a worker”The worker runtime does not start a flow on its own. Following the App Execution Lifecycle, the usual path is:
- a core event occurs or a schedule matches
- a trigger selects a task
- the task resolves to a handler
- the handler points to a runtime worker
- 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.
Running and inspecting workers locally
Section titled “Running and inspecting workers locally”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:
./dx logsFor the full list of ./dx commands, including service reload/restart options,
run:
./dx helpChecks and tests
Section titled “Checks and tests”Use ./dx for the standard contributor checks. Linting, formatting, and
type-checking are shared across the monorepo:
./dx check all./dx check eslint./dx check prettier./dx check tscRun unit tests for the worker package, and the worker end-to-end suite, with:
./dx unit core-worker./dx e2e core-workerRefer 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-workerand helpers inpackages/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.jsonmanifest underruntimeWorkers, and the event → trigger → task → worker flow - App Worker SDK — the
@lombokapp/app-worker-sdkcode 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.
Contributor mental model
Section titled “Contributor mental model”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.