Skip to content

effect-mqBackground jobs for Effect.

Schema-typed payloads, swappable storage, and at-least-once execution in one package.

The whole idea, in one file

ts
import { Job, Worker } from "effect-mq"
import { DrizzleJobStore } from "effect-mq/drizzle-postgres"
import { Effect, Layer, Schema } from "effect"

// 1. Define once: shared by producers and runners.
class GenerateInvoice extends Job.make("generate-invoice", {
  payload: { invoiceId: Schema.String },
  idempotencyKey: ({ invoiceId }) => invoiceId,
  defaults: { attempts: 5, backoff: { type: "exponential", delay: "1 second" } }
}) {}

// 2. Produce: needs the store, never the worker.
const jobId = yield* GenerateInvoice.enqueue({ invoiceId: "inv_123" })

// 3. Run: a layer, wherever you deploy it.
const RunnerLive = GenerateInvoice.toLayer(
  ({ invoiceId }) => Effect.log(`rendering ${invoiceId}`),
  { concurrency: 5 }
).pipe(Layer.provideMerge(Worker.layer()))
sh
bun add effect-mq   # or npm / pnpm / yarn