Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
inngest avatar

Inngest Middleware

  • 3k installs
  • 27 repo stars
  • Updated July 2, 2026
  • inngest/inngest-skills

inngest-middleware is an agent skill that guides Inngest v4 middleware for logging, Sentry, encryption, dependency injection, and custom telemetry across durable functions.

About

inngest-middleware is an agent skill for cross-cutting concerns on Inngest durable functions through client-level and function-level middleware hooks. It documents structured logging, tracing, Sentry error tracking, payload encryption via @inngest/middleware-encryption, dependency injection with dependencyInjectionMiddleware, custom telemetry, and uniform behavior across many functions. The v4 middleware lifecycle covers onFunctionRun hooks such as beforeExecution, afterExecution, and transformOutput plus onSendEvent transformInput for outbound event payloads. Official packages include encryption middleware with key rotation support and sentryMiddleware requiring Sentry 8 or newer. Custom InngestMiddleware examples show metrics histograms and robust error handling that logs middleware failures without breaking function execution. Best practices require one concern per middleware, graceful error handling, performance awareness, proper typing, and testing with createMockContext and createMockFunction. The skill warns not to install @inngest/realtime on v4 because step.realtime.publish is built in. Developers reach for it when wiring logging, Sentry, encryption, dependency injection,.

  • Documents v4 middleware lifecycle hooks for function runs and outbound event transforms.
  • Covers built-in dependencyInjectionMiddleware plus @inngest/middleware-encryption and @inngest/middleware-sentry package
  • Shows custom metrics middleware with beforeExecution, afterExecution, and transformOutput counters.
  • Warns v4 projects must not use @inngest/realtime middleware because realtime publish is native.
  • Best practices emphasize one concern per middleware, graceful failures, and thorough unit testing.

Inngest Middleware by the numbers

  • 2,957 all-time installs (skills.sh)
  • +54 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #153 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
  • Security screen: MEDIUM risk (skills.sh audit)
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
At a glance

inngest-middleware capabilities & compatibility

Capabilities
custom inngestmiddleware lifecycle hooks · built in dependency injection middleware · official encryption and sentry packages · metrics and performance tracking patterns · middleware error handling without breaking funct
Use cases
orchestration · api development
From the docs

What inngest-middleware says it does

Middleware allows code to run at various points in an Inngest client's lifecycle - during function execution, event sending, and more.
SKILL.md
For Realtime use the `inngest-realtime` skill, NOT this one.
SKILL.md
npx skills add https://github.com/inngest/inngest-skills --skill inngest-middleware

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3k
repo stars27
Security audit3 / 3 scanners passed
Last updatedJuly 2, 2026
Repositoryinngest/inngest-skills

How do I add logging, error tracking, encryption, or shared clients uniformly across many Inngest functions?

Add logging, Sentry, encryption, dependency injection, and custom telemetry middleware across Inngest durable functions.

Who is it for?

Developers adding observability, encryption, or dependency injection across Inngest durable function fleets.

Skip if: Skip when configuring Inngest Realtime on v4 or when the task is only function business logic without cross-cutting hooks.

When should I use this skill?

User adds Inngest middleware for logging, Sentry, encryption, dependency injection, metrics, or uniform error handling.

What you get

Client and function middleware configured with v4 lifecycle hooks, official encryption and Sentry packages, and tested custom middleware patterns.

  • Configured Inngest middleware client setup

Files

SKILL.mdMarkdownGitHub ↗

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 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 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 nativelystep.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

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

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 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

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

npm install @inngest/middleware-encryption
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

npm install @inngest/middleware-sentry
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

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

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
  • Built-in Middleware Reference

Related skills

Forks & variants (1)

Inngest Middleware has 1 known copy in the catalog totaling 34 installs. They canonicalize to this original listing.

How it compares

Use inngest-middleware when wiring Inngest-specific encryption or Sentry packages rather than generic Express middleware patterns.

FAQ

Should I use @inngest/realtime middleware on Inngest v4?

No. v4 ships realtime natively via step.realtime.publish; the v3 realtime middleware package causes runtime errors on v4.

What is the middleware execution order?

Client middleware runs first in array order, then function-level middleware runs in the order specified on createFunction.

Which official middleware packages exist?

@inngest/middleware-encryption for step data encryption and @inngest/middleware-sentry for Sentry tracing with Sentry 8 or newer.

Is Inngest Middleware safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Automation & Workflowsintegrationsbackend

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.