{"id":43831,"library":"sidetrack","title":"Sidetrack","description":"Sidetrack is a TypeScript-first job processing library backed by PostgreSQL (current version 0.1.14). It is actively developed with a focus on simplicity, reliability, and TypeScript ergonomics. Unlike general-purpose message brokers (like RabbitMQ or Redis-based queues), Sidetrack leverages Postgres as both the backing store and the scheduling engine, enabling transactional enqueuing and strong consistency. It supports delayed jobs, retries, concurrency control, and rate limiting. The library is designed for serverless and Edge environments where a single Postgres database is already in use, avoiding additional infrastructure. It requires a running Postgres instance and the pg driver. While still in early development (pre-1.0), it has a growing community and is considered stable for production use. Release cadence is irregular but frequent (several minor releases per month).","status":"active","version":"0.1.14","language":"javascript","source_language":"en","source_url":"https://github.com/sidetracklabs/sidetrack","tags":["javascript","background","jobs","queue","worker","postgresql","postgres","tasks","typescript"],"install":[{"cmd":"npm install sidetrack","lang":"bash","label":"npm"},{"cmd":"yarn add sidetrack","lang":"bash","label":"yarn"},{"cmd":"pnpm add sidetrack","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"PostgreSQL client for Node.js; required to connect to the database","package":"pg","optional":false}],"imports":[{"note":"ESM-only package; CommonJS require() must use .default or destructure.","wrong":"const Sidetrack = require('sidetrack').Sidetrack","symbol":"Sidetrack","correct":"import { Sidetrack } from 'sidetrack'"},{"note":"Job is a named export, not default.","wrong":"import Job from 'sidetrack'","symbol":"Job","correct":"import { Job } from 'sidetrack'"},{"note":"All exports are from the main entry point.","wrong":"import { Queue } from 'sidetrack/queue'","symbol":"Queue","correct":"import { Queue } from 'sidetrack'"}],"quickstart":{"code":"import { Sidetrack } from 'sidetrack';\nimport { Pool } from 'pg';\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL ?? 'postgres://localhost:5432/mydb' });\n\nconst st = new Sidetrack({ pool });\n\nasync function main() {\n  await st.init(); // Creates necessary tables\n\n  // Define a worker\n  st.worker('email', async (job) => {\n    console.log(`Sending email to ${job.data.to}`);\n    // ... send email\n  });\n\n  // Enqueue a job\n  await st.enqueue('email', { to: 'user@example.com', subject: 'Hello' });\n\n  // Start processing\n  await st.start();\n\n  // Graceful shutdown\n  process.on('SIGINT', async () => {\n    await st.stop();\n    process.exit(0);\n  });\n}\n\nmain().catch(console.error);","lang":"typescript","description":"Initialize Sidetrack with a pg Pool, define a worker, enqueue a job, start processing, and handle graceful shutdown."},"warnings":[{"fix":"Upgrade to v0.1.0+ and pass an options object with a `pool` property (an instance of `pg.Pool`).","message":"v0.1.0 changed the constructor signature from `new Sidetrack(connectionString)` to `new Sidetrack({ pool })`.","severity":"breaking","affected_versions":"0.0.x"},{"fix":"Ensure all `worker()` calls happen before `start()`.","message":"Job handlers must be registered before calling `start()`. Registering after start results in undefined behavior.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Call `await st.init()` right after creating the Sidetrack instance.","message":"The `init()` method must be called before any enqueue or worker operations; it creates the required database tables.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Replace `addWorker(name, handler)` with `worker(name, handler)`.","message":"The method `addWorker()` is deprecated since v0.1.10; use `worker()` instead.","severity":"deprecated","affected_versions":"<0.1.10"},{"fix":"Define an interface and use `st.enqueue<MyData>('queue', data)`.","message":"When using TypeScript, job data types must be explicitly provided for type safety; otherwise inferred as `any`.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"search_vec":"'-1.0':108 '0.1.14':16 'activ':19 'addit':90 'alreadi':86 'avoid':89 'back':11,49 'background':133 'base':41 'broker':35 'cadenc':122 'communiti':113 'concurr':66 'consid':116 'consist':60 'control':67 'current':14 'databas':84 'delay':63 'design':74 'develop':20,106 'driver':101 'earli':105 'edg':78 'enabl':55 'engin':54 'enqueu':57 'environ':79 'ergonom':29 'first':7 'focus':23 'frequent':126 'general':32 'general-purpos':31 'grow':112 'infrastructur':91 'instanc':97 'irregular':124 'javascript':132 'job':8,64,134 'leverag':44 'librari':10,72 'like':36 'limit':70 'messag':34 'minor':128 'month':131 'per':130 'pg':100 'postgr':45,83,96,138 'postgresql':13,137 'pre':107 'process':9 'product':119 'purpos':33 'queue':42,135 'rabbitmq':37 'rate':69 'redi':40 'redis-bas':39 'releas':121,129 'reliabl':26 'requir':93 'retri':65 'run':95 'schedul':53 'serverless':76 'sever':127 'sidetrack':1,2,43 'simplic':25 'singl':82 'stabl':117 'still':103 'store':50 'strong':59 'support':62 'task':139 'transact':56 'typescript':6,28,140 'typescript-first':5 'unlik':30 'use':88,120 'version':15 'worker':136","created_at":"2026-06-05T17:01:40.927738+00:00","updated_at":"2026-06-05T17:01:40.927738+00:00","problems":[{"fix":"Call `await st.init()` before any other operations.","cause":"The database tables have not been created. You forgot to call `st.init()`.","error":"Error: relation \"sidetrack_jobs\" does not exist"},{"fix":"Update to v0.1.10+ and use `st.worker(name, handler)`.","cause":"Using an older version of Sidetrack (<0.1.10) where the method was named `addWorker`.","error":"TypeError: st.worker is not a function"},{"fix":"Add a generic type: `st.enqueue<YourDataType>('queue', data)`.","cause":"TypeScript cannot infer the job data type. The enqueue call lacks a generic type parameter.","error":"No overload matches this call. Overload 1 of 2, \"(data: never): ...\" gave the following error."},{"fix":"Update to `new Sidetrack({ pool: new Pool({ connectionString }) })`.","cause":"Passed a connection string instead of a Pool object to the Sidetrack constructor (pre-v0.1.0 pattern).","error":"Error: pool is not a Pool instance"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/sidetracklabs/sidetrack#readme","github":"https://github.com/sidetracklabs/sidetrack","docs":null,"changelog":null,"pypi":null,"npm":"sidetrack","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-05","next_check":"2026-09-03","install_tag":null}}