install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/TerminalSkills/skills/trigger-dev" ~/.claude/skills/comeonoliver-skillshub-trigger-dev && rm -rf "$T"
manifest:
skills/TerminalSkills/skills/trigger-dev/SKILL.mdsource content
Trigger.dev — Background Jobs for TypeScript
You are an expert in Trigger.dev, the open-source background jobs platform for TypeScript. You help developers build reliable long-running tasks, scheduled jobs, webhook handlers, and event-driven workflows with automatic retries, concurrency control, real-time logs, and deployment to serverless infrastructure — replacing BullMQ/Redis setups with a fully managed or self-hosted solution purpose-built for modern TypeScript apps.
Core Capabilities
Task Definition
// trigger/tasks/process-order.ts import { task, wait, logger, retry } from "@trigger.dev/sdk/v3"; export const processOrder = task({ id: "process-order", retry: { maxAttempts: 3, factor: 2, minTimeoutInMs: 1000, maxTimeoutInMs: 30000, }, run: async (payload: { orderId: string; userId: string }) => { logger.info("Processing order", { orderId: payload.orderId }); // Step 1: Validate const order = await db.orders.findById(payload.orderId); if (!order) throw new Error(`Order ${payload.orderId} not found`); // Step 2: Charge payment (auto-retries on failure) const payment = await retry.onThrow( async () => stripe.paymentIntents.create({ amount: order.total * 100, currency: "usd", customer: order.stripeCustomerId, }), { maxAttempts: 3, randomize: true }, ); logger.info("Payment charged", { paymentId: payment.id }); // Step 3: Wait for webhook confirmation (durable wait) const confirmation = await wait.for({ seconds: 300 }); // Step 4: Send notification await sendEmail(order.userEmail, "order-confirmed", { orderId: order.id }); return { orderId: order.id, paymentId: payment.id, status: "completed" }; }, }); // Scheduled task (cron) export const dailyReport = task({ id: "daily-report", run: async () => { const stats = await db.orders.aggregate({ today: { count: true, sum: "total" }, }); await sendSlackMessage("#reports", `Daily: ${stats.count} orders, $${stats.sum}`); }, });
Triggering Tasks
// From your API route import { tasks } from "@trigger.dev/sdk/v3"; // Trigger and forget await tasks.trigger("process-order", { orderId: "ord-123", userId: "usr-456", }); // Trigger and wait for result const result = await tasks.triggerAndWait("process-order", { orderId: "ord-123", userId: "usr-456", }); // Batch trigger await tasks.batchTrigger("process-order", [ { payload: { orderId: "ord-1", userId: "usr-1" } }, { payload: { orderId: "ord-2", userId: "usr-2" } }, { payload: { orderId: "ord-3", userId: "usr-3" } }, ]); // Schedule await tasks.schedule("daily-report", { cron: "0 9 * * *", // Daily at 9 AM timezone: "America/New_York", }); // Delayed await tasks.trigger("send-reminder", { userId: "usr-456", }, { delay: "24h", // Run in 24 hours });
Webhook Handler
import { task } from "@trigger.dev/sdk/v3"; export const handleStripeWebhook = task({ id: "stripe-webhook", run: async (payload: { type: string; data: any }) => { switch (payload.type) { case "payment_intent.succeeded": await db.orders.update(payload.data.metadata.orderId, { status: "paid" }); await tasks.trigger("ship-order", { orderId: payload.data.metadata.orderId }); break; case "customer.subscription.deleted": await handleChurn(payload.data.customer); break; } }, });
Installation
npx trigger.dev@latest init # Initialize in existing project npx trigger.dev@latest dev # Local development npx trigger.dev@latest deploy # Deploy to Trigger.dev cloud
Best Practices
- Idempotent tasks — Design tasks to be safely retried; use unique IDs for payment/email operations
- Structured logging — Use
with objects; visible in Trigger.dev dashboardlogger.info/warn/error - Retry configuration — Set appropriate retry strategies per task; payment tasks need different retries than emails
- Concurrency limits — Set
to prevent overwhelming downstream servicesconcurrencyLimit - Wait for events — Use
for durable waits; task resumes even after server restartswait.for - Batch for throughput — Use
for bulk operations; processed in parallel with concurrency controlbatchTrigger - Environment separation — Use dev/staging/prod environments; preview deployments for testing
- Self-hosted option — Deploy Trigger.dev on your own infra with Docker; full control over data and execution