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, @runlane/lane-postgres-polling, or @runlane/lane-postgres-sqs | Storage and delivery resource 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 delivery resource 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 transport-delivery trigger() calls try to publish new outbox rows immediately or leave 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 plus delivery mode 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. Use Postgres polling when workers should poll Postgres directly:
import { postgresPollingLane } from '@runlane/lane-postgres-polling'
const lane = postgresPollingLane({
connectionString: process.env.DATABASE_URL,
schema: 'runlane',
})Use Postgres/SQS when a provider should deliver wakeups:
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-polling | postgresPollingLane() | connectionString, optional schema, optional lane name. |
@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 Polling Lane, 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 }), postgresPollingLane({ 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.