mcpField
I
inngest-nextjs-patterns

inngest-nextjs-patterns

github.com/pproencaDevelopment218131 installsUpdated 11w ago
Repository

About inngest-nextjs-patterns

inngest-nextjs-patterns provides templates and conventions for durable, event-driven background work in Next.js App Router projects using Inngest. It covers events, functions, and scheduled work, with guidance on stable IDs and idempotent steps.

Key features

  1. 01Templates for the Inngest client and route
  2. 02Typed events with Zod schemas
  3. 03Event-triggered durable functions
  4. 04Scheduled tasks and fan-out orchestration
  5. 05Conventions for retries, concurrency, and idempotency

Use cases

  1. 01Set up Inngest in a Next.js project
  2. 02Add background jobs, webhooks, or scheduled tasks
  3. 03Build multi-step workflows that survive restarts
  4. 04Review event naming and step idempotency

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pproenca/dot-skills --skill inngest-nextjs-patterns

After installing, type/inngest-nextjs-patternsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

config.json
gotchas.md
metadata.json
assets/templates/
client.ts.template
event.ts.template
function-cron.ts.template
function-fan-out.ts.template
function.ts.template
route-handler.ts.template
references/
conventions.md

Details

From the project README

Inngest + Next.js Patterns

Templates and conventions for building event-driven, durable background work on Inngest from a Next.js App Router project. The skill enforces the conventions Inngest's own docs use (decentralized eventType() schemas, kebab-case stable function IDs, idempotent steps) so that retries, replays, and concurrency controls actually do what they advertise.

When to Apply

Read this skill when you are:

  • Setting up Inngest in a Next.js app for the first time (client + route handler + first function)
  • Adding a new background job, webhook handler, or scheduled task to a Next.js app
  • Defining a new domain event that other functions will trigger on
  • Orchestrating multi-step work that must survive process restarts (durable workflows, sagas)
  • Reviewing existing Inngest code for event naming, step idempotency, or stable function IDs
  • Migrating from setTimeout / a queue library / a cron service to Inngest's durable execution model

How to Use

  1. First time in this codebase? Read references/conventions.md before writing anything. The conventions explain why event names take a specific shape, why function IDs must be stable, and why every step.run must be idempotent — once you understand the reasoning, the templates make sense.
  2. Pick a template from the catalog below based on what you're creating.
  3. Render it by substituting the documented parameters. Each template has a parameter table at the top of its file.
  4. Wire it up: new functions must be added to src/inngest/functions/index.ts (the registry the route handler reads). The conventions doc shows the registry pattern.

Available Templates

TemplateOutput PathUse When
client.ts.templatesrc/inngest/client.tsOne-time setup: create the singleton Inngest client. Generate once per app.
route-handler.ts.templatesrc/app/api/inngest/route.tsOne-time setup: the App Router endpoint Inngest hits to invoke your functions. Generate once per app.
event.ts.templatesrc/inngest/events/{domain}.tsDefining a new typed event (with Zod schema) that producers send and functions consume.
function.ts.templatesrc/inngest/functions/{name}.tsStandard event-triggered durable function with steps. Parameterized retries, concurrency, throttle, debounce, cancelOn, onFailure.
function-cron.ts.templatesrc/inngest/functions/{name}.tsScheduled function — runs on a cron expression (with timezone). Optionally also accepts a manual event trigger for ad-hoc invocation.
function-fan-out.ts.templatesrc/inngest/functions/{name}.tsOrchestrator that receives one event and fans out work — via step.sendEvent (fire-and-forget) or Promise.all(step.invoke(...)) (wait for results).

Quick Reference

  • Event name shape: domain/entity.verb_past — e.g., app/user.created, shop/order.placed, billing/invoice.paid. The conventions doc has the full rule.
  • Function id: stable kebab-case, never rename it after deploy — Inngest uses it as the durable state key.
  • Step id: descriptive kebab-case, also durable; changing one re-runs that step on replay.
  • Idempotency: every step.run must be safely retryable. If it calls a third-party API that mutates state, pass an idempotency key.
  • Dev server: npx inngest-cli@latest dev, then UI at http://localhost:8288. Set INNGEST_DEV=1 in .env.local to point the SDK at it.

Project Layout Assumption

Templates assume a src/ directory with App Router:

src/
├── app/api/inngest/route.ts          # generated by route-handler template
└── inngest/
    ├── client.ts                     # generated by client template
    ├── events/                       # one file per domain (events.shop.ts, events.user.ts)
    │   └── {domain}.ts               # generated by event template
    └── functions/
        ├── index.ts                  # registry: re-exports all functions as an array
        └── {name}.ts                 # generated by function/cron/fan-out templates

If your project uses a different layout (no src/, or Pages Router), override the output paths in config.json. The conventions doc explains the trade-offs.

Setup

config.json controls path overrides. On first use, check whether its fields are filled in — if not, ask the user before generating (project root differs from the default assumption).

Related Skills

  • vercel:ai-sdk — if your Inngest functions invoke LLMs, the AI SDK gives you streaming + provider abstraction; pair them with step.run for retry safety.
  • vercel:vercel-functions — Inngest's serve() adapter for Next.js runs as a Vercel Serverless Function by default; the AI SDK skill has notes on Fluid Compute and timeout extension for long agent runs.

Comments

Markdown supported