https://github.com/kvet/queuert
Control flow library for your persistency layer driven applications
https://github.com/kvet/queuert
background-jobs job-queue mongodb nodejs postgresql queue sqlite transactional-outbox typescript workflow
Last synced: 29 days ago
JSON representation
Control flow library for your persistency layer driven applications
- Host: GitHub
- URL: https://github.com/kvet/queuert
- Owner: kvet
- License: mit
- Created: 2025-10-28T06:50:21.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-03-31T20:24:58.000Z (about 1 month ago)
- Last Synced: 2026-03-31T20:40:59.327Z (about 1 month ago)
- Topics: background-jobs, job-queue, mongodb, nodejs, postgresql, queue, sqlite, transactional-outbox, typescript, workflow
- Language: TypeScript
- Homepage: https://kvet.github.io/queuert/
- Size: 3.39 MB
- Stars: 18
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Queuert
[](https://www.npmjs.com/package/queuert)
[](https://github.com/kvet/queuert/blob/main/LICENSE)
Control flow library for your persistency layer driven applications.
[**Documentation**](https://kvet.github.io/queuert/) | [**Getting Started**](https://kvet.github.io/queuert/getting-started/introduction/)
Run your application logic as a series of background jobs that are started alongside state change transactions in your persistency layer. Perform long-running tasks with side-effects reliably in the background and keep track of their progress in your database. Own your stack and avoid vendor lock-in by using the tools you trust.
## Quick Example
Imagine a user signs up and you want to send them a welcome email. You don't want to block the registration request, so you queue it as a background job.
```ts
const jobTypeRegistry = defineJobTypeRegistry<{
"send-welcome-email": {
entry: true;
input: { userId: number; email: string; name: string };
output: { sentAt: string };
};
}>();
const client = await createClient({
stateAdapter,
jobTypeRegistry,
});
await withTransactionHooks(async (transactionHooks) =>
db.transaction(async (tx) => {
const user = await tx.users.create({
name: "Alice",
email: "alice@example.com",
});
await client.startJobChain({
tx,
transactionHooks,
typeName: "send-welcome-email",
input: { userId: user.id, email: user.email, name: user.name },
});
}),
);
```
We scheduled the job inside a database transaction. This ensures that if the transaction rolls back (e.g., user creation fails), the job is not started. No orphaned emails. (Refer to transactional outbox pattern.)
Later, a background worker picks up the job and sends the email:
```ts
const worker = await createInProcessWorker({
client,
jobTypeProcessorRegistry: createJobTypeProcessorRegistry({
client,
jobTypeRegistry,
processors: {
"send-welcome-email": {
attemptHandler: async ({ job, complete }) => {
await sendEmail({
to: job.input.email,
subject: "Welcome!",
body: `Hello ${job.input.name}, welcome to our platform!`,
});
return complete(async () => ({
sentAt: new Date().toISOString(),
}));
},
},
},
}),
});
const stop = await worker.start(); // Call stop() for graceful shutdown
```
## Why Queuert?
- **Your database is the source of truth** — No separate persistence layer. Jobs live alongside your application data.
- **True transactional consistency** — Start jobs inside your database transactions. If the transaction rolls back, the job is never created. No dual-write problems.
- **No vendor lock-in** — Works with PostgreSQL and SQLite. Bring your own ORM (Kysely, Drizzle, Prisma, raw drivers).
- **Simple mental model** — Job chains work like Promise chains. No determinism requirements, no replay semantics to learn.
- **Full type safety** — TypeScript inference for inputs, outputs, continuations, and blockers. Catch errors at compile time.
- **Flexible notifications** — Use Redis, NATS, or PostgreSQL LISTEN/NOTIFY for low-latency. Or just poll—no extra infrastructure required.
- **MIT licensed** — No enterprise licensing concerns.
## Installation
```bash
# Core package (required)
npm install queuert
# State adapters (pick one)
npm install @queuert/postgres # PostgreSQL - recommended for production
npm install @queuert/sqlite # SQLite (experimental)
# Notify adapters (optional, for reduced latency)
npm install @queuert/redis # Redis pub/sub - recommended for production
npm install @queuert/nats # NATS pub/sub (experimental)
# Or use PostgreSQL LISTEN/NOTIFY via @queuert/postgres (no extra infra)
# Dashboard (optional)
npm install @queuert/dashboard # Embeddable web UI for job observation (experimental)
# Observability (optional)
npm install @queuert/otel # OpenTelemetry metrics and tracing
```
## Learn More
Visit the [documentation site](https://kvet.github.io/queuert/) for guides on:
- [Transaction Hooks](https://kvet.github.io/queuert/guides/transaction-hooks/)
- [Job Processing Modes](https://kvet.github.io/queuert/guides/processing-modes/)
- [Job Chain Patterns](https://kvet.github.io/queuert/guides/chain-patterns/)
- [Error Handling](https://kvet.github.io/queuert/guides/error-handling/)
- [Scheduling & Recurring Jobs](https://kvet.github.io/queuert/guides/scheduling/)
- [Deduplication](https://kvet.github.io/queuert/guides/deduplication/)
- [Feature Slices](https://kvet.github.io/queuert/guides/slices/)
- [Horizontal Scaling](https://kvet.github.io/queuert/guides/horizontal-scaling/)
- [Dashboard](https://kvet.github.io/queuert/integrations/dashboard/)
- [Observability](https://kvet.github.io/queuert/integrations/observability/)
- And more...
## License
MIT