From original
to ready.
This path uses PostgreSQL for asset records, AWS S3 for objects, and Redis/BullMQ for background work. The same core also accepts your own repository and storage implementations.
1. Install
npm install renditionkit @aws-sdk/client-s3 pgUse Node.js 20 or newer. Run PostgreSQL, Redis, and an S3 bucket. AWS credentials can come from the usual AWS SDK provider chain.
2. Configure the runtime
Save this as runtime.ts. Set DATABASE_URL, S3_REGION, and S3_BUCKET in the environment. For R2 or MinIO, configure the S3 client endpoint and credentials as appropriate.
import { S3Client } from "@aws-sdk/client-s3";
import { Pool } from "pg";
import { createImageEngine } from "renditionkit/image";
import { createS3Storage } from "renditionkit/storage-s3";
import {
PostgresAssetRepository,
migratePostgresRepository,
} from "renditionkit/repository-postgres";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
await migratePostgresRepository(pool);
export const repository = new PostgresAssetRepository(pool);
export const storage = createS3Storage({
client: new S3Client({ region: process.env.S3_REGION! }),
bucket: process.env.S3_BUCKET!,
});
export const runtime = {
repository,
storage,
engines: [createImageEngine()],
};3. Run a worker
Save this as worker.ts and run it in a separate Node process. The worker loads the asset from PostgreSQL, reads the original, generates renditions, writes them to storage, then marks the asset ready.
import { createMediaWorker } from "renditionkit/bullmq";
import { runtime } from "./runtime.js";
const handle = createMediaWorker({
connection: { host: "127.0.0.1", port: 6379 },
runtime,
concurrency: 2,
});
process.once("SIGTERM", () => void handle.close());4. Enqueue an asset
Save this as enqueue.ts. Put a real JPEG at ./example.jpg. The original is stored before its durable asset record is enqueued.
import { readFile } from "node:fs/promises";
import { createMediaQueue } from "renditionkit/bullmq";
import { repository, storage } from "./runtime.js";
const sourceKey = "originals/example.jpg";
await storage.put({
key: sourceKey,
body: await readFile("./example.jpg"),
contentType: "image/jpeg",
});
const asset = await repository.create({
mediaType: "image",
sourceKey,
});
const media = createMediaQueue({
connection: { host: "127.0.0.1", port: 6379 },
});
await media.enqueue(asset.id);
await media.close();