Receber por email
← Voltar para o catálogo

inngest

Inngest expert for serverless-first background jobs, event-driven

41.2kestrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add sickn33/antigravity-awesome-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/inngest-mpteh9zp/svg)](https://www.skillteca.com.br/skills/inngest-mpteh9zp)

Skills relacionadas

Ver todas de Desenvolvimento →

Alerta por categoria

Receba novas skills de Desenvolvimento toda segunda

1 email curto, só com as skills novas de Desenvolvimento. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Inngest Integration

Inngest expert for serverless-first background jobs, event-driven workflows, and durable execution without managing queues or workers.

Principles

  • Events are the primitive - everything triggers from events, not queues
  • Steps are your checkpoints - each step result is durably stored
  • Sleep is not a hack - Inngest sleeps are real, not blocking threads
  • Retries are automatic - but you control the policy
  • Functions are just HTTP handlers - deploy anywhere that serves HTTP
  • Concurrency is a first-class concern - protect downstream services
  • Idempotency keys prevent duplicates - use them for critical operations
  • Fan-out is built-in - one event can trigger many functions

Capabilities

  • inngest-functions
  • event-driven-workflows
  • step-functions
  • serverless-background-jobs
  • durable-sleep
  • fan-out-patterns
  • concurrency-control
  • scheduled-functions

Scope

  • redis-queues -> bullmq-specialist
  • workflow-orchestration -> temporal-craftsman
  • message-streaming -> event-architect
  • infrastructure -> infra-architect

Tooling

Core

  • inngest
  • inngest-cli

Frameworks

  • nextjs
  • express
  • hono
  • remix
  • sveltekit

Deployment

  • vercel
  • cloudflare-workers
  • netlify
  • railway
  • fly-io

Patterns

  • step-functions
  • event-fan-out
  • scheduled-cron
  • webhook-handling

Patterns

Basic Function Setup

Inngest function with typed events in Next.js

When to use: Starting with Inngest in any Next.js project

// lib/inngest/client.ts import { Inngest } from 'inngest';

export const inngest = new Inngest({ id: 'my-app', schemas: new EventSchemas().fromRecord<Events>(), });

// Define your events with types type Events = { 'user/signed.up': { data: { userId: string; email: string } }; 'order/placed': { data: { orderId: string; total: number } }; };

// lib/inngest/functions.ts import { inngest } from './client';

export const sendWelcomeEmail = inngest.createFunction( { id: 'send-welcome-email' }, { event: 'user/signed.up' }, async ({ event, step }) => { // Step 1: Get user details const user = await step.run('get-user', async () => { return await db.users.findUnique({ where: { id: event.data.userId } }); });

// Step 2: Send welcome email await step.run('send-email', async () => { await resend.emails.send({ to: user.email, subject: 'Welcome!', template: 'welcome', }); });

// Step 3: Wait 24 hours, then send tips await step.sleep('wait-for-tips', '24h');

await step.run('send-tips', async () => { await resend.emails.send({ to: user.email, subject: 'Getting Started Tips', template: 'tips', }); }); } );

// app/api/inngest/route.ts (Next.js App Router) import { serve } from 'inngest/next'; import { inngest } from '@/lib/inngest/client'; import { sendWelcomeEmail } from '@/lib/inngest/functions';

export const { GET, POST, PUT } = serve({ client: inngest, functions: [sendWelcomeEmail], });

Multi-Step Workflow

Complex workflow with parallel steps and error handling

When to use: Processing that involves multiple services or long waits

export const processOrder = inngest.createFunction( { id: 'process-order', retries: 3, concurrency: { limit: 10 }, // Max 10 orders processing at once }, { event: 'order/placed' }, async ({ event, step }) => { const { orderId } = event.data;

// Parallel steps - both run simultaneously const [inventory, payment] = await Promise.all([ step.run('check-inventory', () => checkInventory(orderId)), step.run('validate-payment', () => validatePayment(orderId)), ]);

if (!inventory.available) { // Send event instead of direct call (fan-out pattern) await step.sendEvent('notify-backorder', { name: 'order/backordered', data: { orderId, items: inventory.missing }, }); return { status: 'backordered' }; }

// Process payment const charge = await step.run('charge-payment', async () => { return await stripe.charges.create({ amount: event.data.total, customer: payment.customerId, }); });

// Ship order await step.run('ship-order', () => fulfillment.ship(orderId));

return { status: 'completed', chargeId: charge.id }; } );

Scheduled/Cron Functions

Functions that run on a schedule

When to use: Recurring tasks like daily reports or cleanup jobs

export const dailyDigest = inngest.createFunction( { id: 'daily-digest' }, { cron: '0 9 *' }, // Every day at 9am UTC async ({ step }) => { // Get all users who want digests const users = await step.run('get-users', async () => { return await db.users.findMany({ where: { digestEnabled: true }, }); });

// Send to each user (creates child events) await step.sendEvent( 'send-digests', users.map(user => ({ name: 'digest/send', data: { userId: user.id }, })) );

return { sent: users.length }; } );

// Separate function handles individual digest sending export const sendDigest = inngest.createFunction( { id: 'send-digest', concurrency: { limit: 50 } }, { event: 'digest/send' }, async ({ event, step }) => { // ... send individual digest } );

Webhook Handler with Idempotency

Safely process webhooks with deduplication

When to use: Handling Stripe, GitHub, or other webhooks

export const handleStripeWebhook = inngest.createFunction( { id: 'stripe-webhook', // Deduplicate by Stripe event ID idempotency: 'event.data.stripeEventId', }, { event: 'stripe/webhook.received' }, async ({ event, step }) => { const { type, data } = event.data;

switch (type) { case 'checkout.session.completed': await step.run('fulfill-order', async () => { await fulfillOrder(data.session.id); }); break;

case 'customer.subscription.deleted': await step.run('cancel-subscription', async () => { await cancelSubscription(data.subscription.id); }); break; } } );

AI Pipeline with Long Processing

Multi-step AI processing with chunked work

When to use: AI workflows that may take minutes to complete

export const processDocument = inngest.createFunction( { id: 'process-document', retries: 2, concurrency: { limit: 5 }, // Limit API usage }, { event: 'document/uploaded' }, async ({ event, step }) => { // Step 1: Extract text (may take a while) const text = await step.run('extract-text', async () => { return await extractTextFromPDF(event.data.fileUrl); });

// Step 2: Chunk for embedding const chunks = await step.run('chunk-text', async () => { return chunkText(text, { maxTokens: 500 }); });

// Step 3: Generate embeddings (API rate limited) const embeddings = await step.run('generate-embeddings', async () => { return await openai.embeddings.create({ model: 'text-embedding-3-small', input: chunks, }); });

// Step 4: Store in vector DB await step.run('store-vectors', async () => { await vectorDb.upsert({ vectors: embeddings.data.map((e, i) => ({ id: ${event.data.documentId}-${i}, values: e.embedding, metadata: { chunk: chunks[i] }, })), }); });

return { chunks: chunks.length, status: 'indexed' }; } );

Validation Checks

Inngest serve handler present

Severity: CRITICAL

Message: Inngest requires a serve handler to receive events

Fix action: Create app/api/inngest/route.ts with serve() export

Functions registered with serve

Severity: ERROR

Message: Ensure all Inngest functions are registered in the serve() call

Fix action: Add function to the functions array in serve()

Step.run has descriptive name

Severity: WARNING

Message: Step names should be kebab-case a

Compartilhar X LinkedIn