Configuration
Choose the right Runlane configuration surface.
Runlane configuration is code. There is no project-wide YAML file and no hidden task discovery step. Your application creates a runtime with createRunlane(), wires a lane, registers queues and tasks, and exports that same runtime to processes that need to trigger, execute, maintain, or inspect runs.
Use this page to choose the right surface before changing config.
| Surface | Where it lives | Use it for |
|---|---|---|
| Runtime construction | createRunlane() from @runlane/core | Queues, tasks, environment, dispatch policy, clock, and default worker id. |
| Lane construction | Lane packages such as @runlane/lane-local or @runlane/lane-postgres-sqs | Storage and transport composition. |
| Adapter options | Packages such as @runlane/postgres-storage and @runlane/transport-sqs | Database connection, schema, SQS client, SQS queue bindings, FIFO options, and adapter batch limits. |
| CLI config | runlane.config.ts or another module passed with --config | A thin adapter that exports the runtime instance or runtime factory used by runlane commands. |
| Deployment environment | Your app, process manager, IaC, and secret store | Values such as DATABASE_URL, SQS queue URLs, AWS region, and runtime environment name. |
Runtime Construction
createRunlane() is the main application configuration boundary. It requires a lane and an explicit queue registry:
import { createRunlane, queue } from '@runlane/core'
import { createLocalLane } from '@runlane/lane-local'
import { sendEmail } from './tasks/send-email.js'
const emailQueue = queue({ name: 'emails', default: true })
export function createAppRunlane() {
return createRunlane({
environment: { name: 'development' },
lane: createLocalLane(),
queues: [emailQueue],
tasks: { sendEmail },
})
}Runtime options are validated when the runtime is created. Unsupported options fail with ErrorCode.ConfigurationInvalid.
| Option | Required | Default | Notes |
|---|---|---|---|
lane | Yes | None | Storage and transport composition. |
queues | Yes | None | Authoritative queue registry. Queue names must be unique. |
tasks | No | Empty registry | Task collection used by workers, schedules, and CLI trigger. Prefer a named object catalog. |
environment | No | { name: 'default' } | Durable namespace used by storage, transport, idempotency, singleton, schedules, and operator reads. |
dispatch.onTrigger | No | Eager dispatch | Controls whether trigger() tries to publish the new outbox row immediately or leaves publishing to tick(). |
clock | No | Wall clock | Deterministic time source for tests and maintenance. |
workerId | No | Generated worker_${uuid} | Default diagnostic worker identity for leases and outbox claims. |
Queue declarations belong in shared application code, not in the CLI config file. The same queue objects should be passed to createRunlane({ queues }), task definitions, and provider bindings such as sqsQueue(queue, options).
See Quick Start for the runtime lifecycle and Queues for queue policies.
Lane And Adapter Options
A lane is the storage and transport pair the runtime uses. Local development normally uses createLocalLane() from @runlane/lane-local; it accepts only an optional diagnostic name and keeps state in the current process.
Production code usually has more adapter configuration:
import { SQSClient } from '@aws-sdk/client-sqs'
import { postgresSqsLane } from '@runlane/lane-postgres-sqs'
import { sqsQueue } from '@runlane/transport-sqs'
const lane = postgresSqsLane({
postgres: {
connectionString: process.env.DATABASE_URL,
schema: 'runlane',
},
sqs: {
client: new SQSClient({ region: process.env.AWS_REGION }),
queues: [
sqsQueue(emailQueue, {
queueUrl: process.env.RUNLANE_EMAILS_QUEUE_URL,
}),
],
},
})postgresSqsLane() validates its top-level shape, then delegates nested validation to the adapter packages:
| Package | Function | Important options |
|---|---|---|
@runlane/lane-postgres-sqs | postgresSqsLane() | postgres, sqs, optional lane name. |
@runlane/postgres-storage | postgresStorage() | connectionString, optional schema. |
@runlane/transport-sqs | sqsTransport() | client, queues, optional batchSize, optional transport name. |
@runlane/transport-sqs | sqsQueue() | Exactly one of queueUrl or queueName, optional queueOwnerAWSAccountId, optional FIFO settings. |
Run Postgres migrations before starting a Postgres-backed lane. lane.start() probes the migrated tables and fails when the database, schema, or migration is not ready.
See Postgres SQS Lane, Postgres Storage, and SQS Transport for adapter contracts and deployment notes.
CLI Config
The packaged runlane binary loads a config module from the current working directory. The default search order is:
runlane.config.tsrunlane.config.mtsrunlane.config.mjsrunlane.config.jsrunlane.config.cjs
Pass --config <path> before the command when the module lives somewhere else.
The config module exports a RunlaneCliConfig object with a runtime value or factory:
import { type RunlaneCliConfig } from '@runlane/cli'
import { createAppRunlane } from './runtime/runlane.ts'
export default {
runtime: createAppRunlane,
} satisfies RunlaneCliConfigKeep this file thin. It should import the application-owned runtime factory rather than rebuilding tasks, queues, lanes, or environment defaults in a second place.
runlane init config --runtime ./runtime/runlane.ts writes this adapter for you. It does not start a runtime or generate lane configuration.
See Runlane CLI for command behavior, --json, runlane dev, worker options, and operator commands.
Environment Values
Runlane does not prescribe an environment variable format. Keep secrets and deployment-specific values in your app's normal configuration system, then pass typed values into the runtime and lane factory.
Common values include:
| Value | Passed to | Notes |
|---|---|---|
| Database URL | postgresStorage({ connectionString }) or postgresSqsLane({ postgres }) | Must use postgres:// or postgresql://. A Prisma-style ?schema= is accepted and removed before connecting. |
| Postgres schema | postgresStorage({ schema }) | Optional. Overrides ?schema= from the URL; defaults to public. |
| AWS region | new SQSClient({ region }) | Owned by the AWS SDK client you pass to SQS transport. |
| SQS queue URL or name | sqsQueue(queue, options) | Each Runlane queue must be bound to exactly one provider queue source. |
| Runtime environment name | createRunlane({ environment }) | Use separate names for durable namespaces that must not share runs, schedules, or idempotency ownership. |
Do not split one logical runtime across mismatched environment names, queue definitions, or SQS bindings. createRunlane() and the transport adapters validate many of these mismatches at startup, but shared constants make them easier to avoid.