Run your first task
Install Runlane, execute one local task, and read its stored result.
In this tutorial, you will create one task, run it in memory, and read its result. The whole example lives in one file.
Before you start
You need Node.js 22.18.0 or newer and an existing TypeScript project. This path uses Node's built-in TypeScript type stripping.
Install Runlane, the local lane, and Zod:
npm install @runlane/core @runlane/lane-local zodCheck that Node meets the package requirement:
node --versionCreate the task
Create runlane-quickstart.mts. The .mts extension makes the example an ES module without depending on your project's package.json module setting:
import { createRunlane, queue, task } from '@runlane/core'
import { createLocalLane } from '@runlane/lane-local'
import * as z from 'zod'
const sendWelcomeEmail = task({
id: 'email.send-welcome',
output: z.object({ sentTo: z.string() }),
schema: z.object({ email: z.email() }),
run: ({ email }) => ({ sentTo: email }),
})
const runlane = createRunlane({
lane: createLocalLane(),
queues: [queue({ name: 'default', default: true })],
tasks: { sendWelcomeEmail },
})
const { run: queuedRun } = await runlane.trigger(runlane.tasks.sendWelcomeEmail, {
email: 'ada@example.com',
})
await runlane.drain()
const storedRun = await runlane.runs.get(runlane.tasks.sendWelcomeEmail, queuedRun.id)
console.log(
JSON.stringify({
queued: queuedRun.status,
completed: storedRun?.status,
output: storedRun?.output,
}),
)
await runlane.close()The payload schema validates input before Runlane creates the run. The output schema validates the result before success and gives storedRun.output its inferred type.
The named task catalog keeps both types tied to the task registered by the worker.
Run the task
node runlane-quickstart.mtsYou should see:
{ "queued": "queued", "completed": "succeeded", "output": { "sentTo": "ada@example.com" } }trigger() stored a queued run. drain() claimed and executed currently due work, then runs.get() read the materialized result from the lane.
What just happened
The local lane keeps all state in the current process. It is useful for development and tests, but process exit deletes its runs and it cannot share work between separate processes.
If it does not work
If the install reports an unsupported engine, upgrade Node to 22.18.0 or newer. If execution returns no completed run after changing the example, confirm that the runtime has exactly one default queue and that the task is present in its tasks catalog.
Next, add Runlane to your app without duplicating runtime configuration.