Agent Native

inngest-middleware

This skill teaches how to implement middleware in Inngest durable functions to handle cross-cutting concerns like structured logging, error tracking…

by InngestOfficial publisherNot reviewed

Identity proven by GitHub's verified organisation badge (inngest)

Agents
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, claude.ai and API
License
Apache-2.0 (permissive)
Pin
082798apinned Oct 9, 2026
Context cost
about 2,400 tokenswhen the skill loads
GitHub stars
28on inngest/inngest-skills
Scripts
None found

What it does

“Use when adding cross-cutting concerns to durable functions — structured logging or tracing across all functions, error tracking with Sentry, payload encryption for sensitive data, dependency injection of clients (DB, Stripe, etc.) into function handlers, custom telemetry, or behavior that should apply uniformly across many functions. Covers Inngest middleware lifecycle, creating custom middleware, dependencyInjectionMiddleware, @inngest/middleware-encryption, @inngest/middleware-sentry, and custom middleware patterns.”
The author's description, from SKILL.md

Generated summary from the skill's own text

This skill teaches how to implement middleware in Inngest durable functions to handle cross-cutting concerns like structured logging, error tracking, dependency injection, and data encryption. Middleware runs at key lifecycle points across all or specific functions, enabling observability, telemetry, and shared client access patterns.

When to use it

  • Adding logging, tracing, or metrics across multiple functions
  • Injecting database or API clients into function handlers
  • Encrypting sensitive data in function payloads and outputs
  • Tracking errors and exceptions with external services like Sentry

When not to

  • Building realtime features in Inngest v4, use inngest-realtime instead
  • Working with Python or Go, refer to language-specific Inngest documentation

Install

These commands install from the publisher's repository and need no account.

skills CLI

npx skills add inngest/inngest-skills --skill inngest-middleware

Installs from the repository's default branch, which may have changed since the commit we checked.

GitHub CLI 2.90 or later

gh skill install inngest/inngest-skills inngest-middleware@082798a627bbe9c3ed3a6638a9f56116a035f122

Installs the commit we checked (082798a).

Copy by hand

Download the folder at 082798a and put it in .claude/skills/inngest-middleware for Claude Code and in .agents/skills/inngest-middleware for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.

Skill folder on GitHub at 082798a

Copy for your agent

A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.

Prompt

Install the agent skill "inngest-middleware" by Inngest.

Source, pinned to commit 082798a627bbe9c3ed3a6638a9f56116a035f122:
https://github.com/inngest/inngest-skills/tree/082798a627bbe9c3ed3a6638a9f56116a035f122/skills/inngest-middleware

1. Download that folder at exactly this commit. Do not use the default branch.
2. Copy every file unchanged, keeping the folder structure, into .claude/skills/inngest-middleware/ for Claude Code and .agents/skills/inngest-middleware/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist.
3. Do not edit the files, and do not run any script in the folder unless I ask you to.
4. When you are done, list the files you copied and where you put them.

Listing and checks: https://www.agentnative.dev/skills/inngest/inngest-middleware-inngest-skills

SKILL.md at the pin

---
name: inngest-middleware
description: Use when adding cross-cutting concerns to durable functions — structured logging or tracing across all functions, error tracking with Sentry, payload encryption for sensitive data, dependency injection of clients (DB, Stripe, etc.) into function handlers, custom telemetry, or behavior that should apply uniformly across many functions. Covers Inngest middleware lifecycle, creating custom middleware, dependencyInjectionMiddleware, @inngest/middleware-encryption, @inngest/middleware-sentry, and custom middleware patterns.
---

# Inngest Middleware

Master Inngest middleware to handle cross-cutting concerns like logging, error tracking, dependency injection, and data transformation. Middleware runs at key points in the function lifecycle, enabling powerful patterns for observability and shared functionality.

> **These skills are focused on TypeScript.** For Python or Go, refer to the [Inngest documentation](https://www.inngest.com/llms.txt) for language-specific guidance. Core concepts apply across all languages.

> **Note:** The middleware system was significantly rewritten in v4. The lifecycle hooks documented here reflect the v4 API. If migrating from v3, consult the [migration guide](https://www.inngest.com/docs-markdown/reference/typescript/v4/migrations/v3-to-v4) for details on breaking changes.

> **⚠ For Realtime use the `inngest-realtime` skill, NOT this one.** Inngest v3 used `realtimeMiddleware()` from `@inngest/realtime` to inject a `publish` arg into function handlers. **v4 ships realtime natively** — `step.realtime.publish` is built-in, no middleware required. Do NOT install `@inngest/realtime` on a v4 project (it's a v3-era package and produces `TypeError: Cls is not a constructor` at runtime). See the `inngest-realtime` skill for the v4 pattern.

## What is Middleware?

Middleware allows code to run at various points in an Inngest client's lifecycle - during function execution, event sending, and more. Think of middleware as hooks into the Inngest execution pipeline.

**When to use middleware:**

- **Observability:** Add logging, tracing, or metrics
- **Dependency injection:** Share client instances across functions
- **Data transformation:** Encrypt/decrypt, validate, or enrich data
- **Error handling:** Custom error tracking and alerting
- **Authentication:** Validate user context or permissions

## Middleware Lifecycle

Middleware can be registered at **client-level** (affects all functions) or **function-level** (affects specific functions).

### Execution Order

```typescript
const inngest = new Inngest({
  id: "my-app",
  middleware: [
    loggingMiddleware, // Runs 1st
    errorMiddleware // Runs 2nd
  ]
});

inngest.createFunction(
  {
    id: "example",
    middleware: [
      authMiddleware, // Runs 3rd
      metricsMiddleware // Runs 4th
    ],
    triggers: [{ event: "test" }]
  },
  async () => {
    /* function code */
  }
);
```

**Order matters:** Client middleware runs first, then function middleware, in the order specified.

## Creating Custom Middleware

### Basic Middleware Structure

```typescript
import { InngestMiddleware } from "inngest";

const loggingMiddleware = new InngestMiddleware({
  name: "Logging Middleware",
  init() {
    // Setup phase - runs when client initializes
    const logger = setupLogger();

    return {
      // Function execution lifecycle
      // Note: `fn` is loosely typed in middleware generics; fn.id works at runtime
      onFunctionRun({ ctx, fn }) {
        return {
          beforeExecution() {
            logger.info("Function starting", {
              functionId: fn.id,
              eventName: ctx.event.name,
              runId: ctx.runId
            });
          },

          afterExecution() {
            logger.info("Function completed", {
              functionId: fn.id,
              runId: ctx.runId
            });
          },

          transformOutput({ result }) {
            // Log function output
            logger.debug("Function output", {
              functionId: fn.id,
              output: result.data
            });

            // Return unmodified result
            return { result };
          }
        };
      },

      // Event sending lifecycle
      onSendEvent() {
        return {
          transformInput({ payloads }) {
            logger.info("Sending events", {
              count: payloads.length,
              events: payloads.map((p) => p.name)
            });

            // Spread to convert readonly array to mutable array
            return { payloads: [...payloads] };
          }
        };
      }
    };
  }
});
```

### Python Implementation

Python middleware follows a similar pattern. See [Dependency Injection Reference](./references/dependency-injection.md) for complete Python examples.

````

## Dependency Injection

Share expensive or stateful clients across all functions. **See [Dependency Injection Reference](./references/dependency-injection.md) for detailed patterns.**

### Quick Example - Built-in DI

```typescript
import { dependencyInjectionMiddleware } from "inngest";

const inngest = new Inngest({
  id: 'my-app',
  middleware: [
    dependencyInjectionMiddleware({
      openai: new OpenAI(),
      db: new PrismaClient(),
    }),
  ],
});

// Functions automatically get injected dependencies
inngest.createFunction(
  { id: "ai-summary", triggers: [{ event: "document/uploaded" }] },
  async ({ event, openai, db }) => {
    // Dependencies available in function context
    const summary = await openai.chat.completions.create({
      messages: [{ role: "user", content: event.data.content }],
      model: "gpt-4",
    });

    await db.document.update({
      where: { id: event.data.documentId },
      data: { summary: summary.choices[0].message.content }
    });
  }
);
````

## Middleware Packages

Beyond `dependencyInjectionMiddleware` (built-in, shown above), Inngest provides official middleware as **separate packages**. **See [Middleware Reference](./references/built-in-middleware.md) for complete details.**

### Encryption Middleware

```bash
npm install @inngest/middleware-encryption
```

```typescript
import { encryptionMiddleware } from "@inngest/middleware-encryption";

const inngest = new Inngest({
  id: "my-app",
  middleware: [
    encryptionMiddleware({
      key: process.env.ENCRYPTION_KEY
    })
  ]
});
```

Automatically encrypts all step data, function output, and event `data.encrypted` field. Supports key rotation via `fallbackDecryptionKeys`.

### Sentry Error Tracking

```bash
npm install @inngest/middleware-sentry
```

```typescript
import * as Sentry from "@sentry/node";
import { sentryMiddleware } from "@inngest/middleware-sentry";

Sentry.init({
  /* your Sentry config */
});

const inngest = new Inngest({
  id: "my-app",
  middleware: [sentryMiddleware()]
});
```

Captures exceptions, adds tracing to each function run, and includes function ID and event names as context. Requires `@sentry/*@>=8.0.0`.

## Common Middleware Patterns

### Metrics and Performance Tracking

```typescript
const metricsMiddleware = new InngestMiddleware({
  name: "Metrics Tracking",
  init() {
    return {
      onFunctionRun({ ctx, fn }) {
        let startTime: number;

        return {
          beforeExecution() {
            startTime = Date.now();
            metrics.increment("inngest.step.started", {
              function: fn.id,
              event: ctx.event.name
            });
          },

          afterExecution() {
            const duration = Date.now() - startTime;
            metrics.histogram("inngest.step.duration", duration, {
              function: fn.id,
              event: ctx.event.name
            });
          },

          transformOutput({ result }) {
            const status = result.error ? "error" : "success";
            metrics.increment("inngest.step.completed", {
              function: fn.id,
              status: status
            });

            return { result };
          }
        };
      }
    };
  }
});
```

### Advanced Patterns

**Authentication:** Validate tokens and inject user context
**Conditional logic:** Apply middleware based on event type or function
**Circuit breakers:** Prevent cascading failures from external services

### Configuration-Based Middleware

Create reusable middleware with configuration options for different environments and use cases. See reference documentation for complete examples.

## Best Practices

### Design Principles

1. **Keep middleware focused:** One concern per middleware
2. **Handle errors gracefully:** Don't let middleware crash functions
3. **Consider performance:** Middleware runs on every execution
4. **Use proper typing:** Let TypeScript infer middleware types
5. **Test thoroughly:** Middleware affects all functions that use it

### Common Use Cases to Implement

- **Retry logic** for transient failures
- **Circuit breakers** for external service calls
- **Request/response logging** for debugging
- **User context enrichment** from external sources
- **Feature flags** for gradual rollouts
- **Custom authentication** and authorization checks

### Error Handling in Middleware

```typescript
const robustMiddleware = new InngestMiddleware({
  name: "Robust Middleware",
  init() {
    return {
      onFunctionRun({ ctx, fn }) {
        return {
          transformOutput({ result }) {
            try {
              // Your middleware logic here
              return performTransformation(result);
            } catch (middlewareError) {
              // Log error but don't break the function
              console.error("Middleware error:", middlewareError);

              // Return original result on middleware failure
              return { result };
            }
          }
        };
      }
    };
  }
});
```

### Testing Middleware

Use Inngest's testing utilities (`createMockContext`, `createMockFunction`) to unit test middleware behavior.

**For complete implementation examples and advanced patterns, see:**

- [Dependency Injection Reference](./references/dependency-injection.md)
- [Built-in Middleware Reference](./references/built-in-middleware.md)

From inngest/inngest-skills at 082798a, shown as plain text under its license: Apache-2.0 (permissive). The license text is in LICENSE.

View SKILL.md on GitHub at 082798a

Files

3 files, 33 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.

Skill folder on GitHub at 082798a

Also in

The same SKILL.md content appears in these places too. We list it once and credit the oldest public source.

All 18 skills from Inngest

More from Inngest

  • inngest-agent-evals

    Builds production evaluation workflows for AI agents on Inngest using direct and deferred scoring, sessions for grouping related runs, step experiments for…

    Claude Code, Codex, Cursor +4 · about 2.6K tokens · pinned 6 days ago

  • inngest-agents

    Build durable AI agents and multi-step agentic workflows using Inngest and AgentKit.

    Claude Code, Codex, Cursor +4 · about 2.1K tokens · pinned 6 days ago

  • inngest-api-cli

    This skill routes the agent to use the Inngest CLI `inngest api` command for operational tasks like debugging runs, querying events, syncing apps, invoking…

    Claude Code, Codex, Cursor +4 · about 1.9K tokens · pinned 6 days ago

  • inngest-api

    This skill enables agents to interact with the Inngest REST API v2 for Cloud operations, raw HTTP requests, and API reference lookups.

    Claude Code, Codex, Cursor +4 · about 1.1K tokens · pinned 6 days ago

  • inngest-brownfield-audit

    This skill audits existing TypeScript or JavaScript codebases to identify where Inngest can improve reliability and durability.

    Claude Code, Codex, Cursor +4 · about 2.5K tokens · pinned 6 days ago

  • inngest-cli

    This skill enables installation and operation of the Inngest CLI for local development and testing with the Dev Server, which provides a browser UI at…

    Claude Code, Codex, Cursor +4 · about 3.4K tokens · pinned 6 days ago

All Backend and APIs skills
  • inngest-events

    This skill teaches event design and delivery patterns for Inngest, covering event payload structure, naming conventions, idempotency with event IDs, scheduled…

    by InngestOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2.9K tokens · pinned 6 days ago

  • inngest-flow-control

    This skill provides Inngest flow control mechanisms to manage API rate limits, prevent duplicate processing, and ensure fair resource allocation.

    by InngestOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2.1K tokens · pinned 6 days ago

  • speech-engine

    This skill integrates ElevenLabs Speech Engine to add real-time voice conversations to custom agent runtimes.

    by ElevenLabsOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2.4K tokens · pinned 6 days ago

  • airflow-plugins

    Builds Airflow 3.1+ plugins that embed FastAPI apps, custom UI pages, React components, middleware, macros, and operator links directly into the Airflow UI…

    by AstronomerOfficial publisher

    Claude Code, Codex, Cursor +4 · about 5.8K tokens · pinned 6 days ago

  • authoring-go-sdk-tasks

    Enables writing Airflow task logic in Go by implementing the Go SDK's native API.

    by AstronomerOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2K tokens · pinned 6 days ago

  • authoring-java-sdk-tasks

    This skill teaches how to write Airflow task logic in Java, Kotlin, or other JVM languages using the Airflow Java SDK.

    by AstronomerOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2.4K tokens · pinned 6 days ago

Open roles at Inngest

No open roles at Inngest on the Agent Native jobs board right now.

Browse the jobs board

The skills listed here are third-party software, collected from public GitHub repositories as a catalog of recent skills and provided as is. Agent Native does not write or control them and is not responsible for any harm, loss or damage caused by installing or using them. Labels and checks describe what we saw at one commit and are not a guarantee. Read a skill's files before you run it. Terms of use