effect-mq README

The project's README from github.com/TeamWarp/effect-mq. As one markdown file: README.md.

effect-mq

Effect-native background jobs: schema-first job definitions, a storage-agnostic queue core, a worker runtime, and a Postgres store that lives inside your drizzle schema. Built on Effect v4; inspired by BullMQ's semantics and effect/workflow's DX.

→ Documentation: effect-mq.com — the package README (packages/effect-mq, also shown on npm) covers the same ground in one page.

Maintained by Warp. We're hiring.

import { Job } from "effect-mq"
import { Effect, Schema } from "effect"

class SendEmail extends Job.make("SendEmail", {
  payload: { to: Schema.String, subject: Schema.String },
  success: Schema.String,
  idempotencyKey: ({ to, subject }) => `${to}:${subject}`,
  metadata: ({ to }) => ({ to }),
  defaults: { attempts: 3, backoff: { type: "exponential", delay: "1 second" } }
}) {}

const producer = Effect.gen(function*() {
  const jobId = yield* SendEmail.enqueue({ to: "[email protected]", subject: "hi" })
})

Highlights

Repository layout

packages/effect-mq        the published package (src + tests, incl. the
                          Postgres and Redis suites under test/)
examples/tour             THE demo: four scenes against real Postgres +
                          Redis (kill -9 durability, dedup, a paused
                          cross-store flow) plus a live dashboard —
                          see examples/tour/README.md
examples/basic            minimal in-memory end-to-end: bun src/main.ts
docker-compose.yml        Postgres 17 (5433) + Redis 8 (6380) for the
                          storage test suites
tools/oxlint/anti-slop    local lint plugin enforcing honest types

Development

bun install
bun run check     # TypeScript 7, per package
bun run lint      # oxlint (incl. anti-slop rules)
bun run test      # vitest 4 + @effect/vitest, TestClock-driven
                  # (storage suites self-skip without their backing service)
bun run test:pg   # docker compose up + the Postgres suite
bun run test:redis  # docker compose up + the Redis suite
bun run ready     # check + lint + test
bun run build     # emit dist (tsc, .ts imports rewritten to .js)

The store conformance suite (effect-mq/testing) runs against the in-memory driver, real Postgres, and real Redis — under TestClock in all cases, because drivers take all time as parameters from the Effect Clock.

Release history lives in CHANGELOG.md; planned work in ROADMAP.md.

Releasing

CI (.github/workflows/ci.yml) runs check/lint/tests (with Postgres and Redis service containers) on every push and PR. Publishing to npm happens on version tags:

# bump "version" in packages/effect-mq/package.json, then
git tag v0.2.0 && git push --tags

The publish job runs npm publish with provenance; it needs an NPM_TOKEN repository secret. The package's prepack builds dist and swaps the dev (TS-source) exports for dist exports; postpack restores them. Verify a release candidate locally with:

cd packages/effect-mq && bun pm pack   # then inspect / install the tarball

License

MIT

effect-mq (TeamWarp/effect-mq)

background-jobs
Searching Database…

What is this?effect-mq is an Effect-native background job and message queue library: schema-first job definitions, a storage-agnostic queue core, a worker runtime, and stores for Postgres (via Drizzle) and Redis.
Is this a library I import, or a separate service I run?It is a TypeScript library split into tree-shakeable modules (core, drizzle-postgres store, redis store, testing kit) that you wire into your own Effect application; there is no standalone server binary.
How do I wire it into my project?Install effect-mq plus the store module you need, re-export the provided drizzle schema factories so drizzle-kit manages the job tables' migrations, then define jobs and run the worker runtime against that store.
Do I need Effect and a Postgres or Redis instance to use this?Yes, it's built on Effect v4 and needs at least one backing store — Postgres (claims via FOR UPDATE SKIP LOCKED and LISTEN/NOTIFY) or Redis (atomic Lua scripts with pub/sub) — plus an in-memory driver for testing or disposable jobs.
What happens if a worker crashes or a job stalls mid-run?Delivery is at-least-once with token-guarded locks, heartbeat renewal, and stalled recovery, and every attempt is persisted to a run ledger in the store rather than kept in worker memory, so retries survive crashes.
How do repeatable cron jobs avoid double-firing across multiple workers?Each occurrence is claimed and enqueued in one atomic store operation, guaranteeing exactly one job per occurrence no matter how many workers are running, regardless of retention settings.
What deduplication options does it offer?It supports pending-dedup, throttle, debounce, and replace-while-delayed, all using a separate dedup key so the actual job id is never rewritten.
Can I send different jobs to different stores?Yes, jobs can be bound to named stores — for example Postgres for business-critical runs and memory or Redis for disposable ones — and this routing is enforced at compile time.
Is there a built-in dashboard UI?No UI is bundled, but effect-mq exposes a dashboard data layer: listing with metadata filters, keyset pagination, polling, retry, and per-job and per-store retention, which you can build a dashboard on top of.
What are similar projects?bull, rq, tork, carno.js, react-starter-kit, rankme.fast, dockhand, asynq
Creator
TeamWarp
Size
0.7 MB
Stars
187
Updated
CommitSep 09
Age
1mo
Commits · 90 Days