本文へ移動
cccskills
無料GitHub で公開

inngest-middleware

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.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md11.2 KB
  • references/built-in-middleware.md12.7 KB
  • references/dependency-injection.md10.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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

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

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

This Repository

These upstream Inngest instructions are vendored for agent tooling and integration work in this monorepo.

Repository Triggers

Use this skill when inngest-middleware matches the current Inngest task. If the right skill is unclear, start with docs/ai/skills/inngest/SKILL.md.

Repository Workflow

  1. Confirm whether the request is agent-tooling guidance or product runtime integration.
  2. Use inngest-brownfield-audit before changing existing app workflows or fragile background work.
  3. Follow this upstream guidance under OpenSpec, root AGENTS.md, repo rulebooks, framework docs, and runtime evidence.
  4. Keep runtime packages, app code, migrations, and INNGEST_* env requirements out of agent-tooling-only changes.

Repository Checklist

  • The task has explicit product-runtime scope before adding Inngest app code or dependencies.
  • Existing workflows were audited before introducing or changing durable workflow behavior.
  • Any MCP usage is backed by a running Inngest dev server on the configured port.
  • Upstream source and license attribution remain documented in docs/ai/skills/inngest/references/upstream.md.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Audit and fix accessibility in Core UI. Use when changing or reviewing buttons, links, forms, validation, dialogs, menus, tabs, tables, keyboard interactions, focus management, accessible names, announcements, contrast, touch targets, reduced motion, or WCAG/a11y behavior.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

Use when building any system where email content triggers actions — AI agent inboxes, automated support handlers, email-to-task pipelines, or any workflow processing untrusted inbound email. Always use this skill when the user wants to receive emails and act on them programmatically, even if they don't mention "agent" — the skill contains critical security patterns (sender allowlists, content filtering, sandboxed processing) that prevent untrusted email from controlling your system.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

anim

無料

Tasteful, subtle web UI animation following Emil Kowalski / animations.dev principles. Use when adding or reviewing interface motion — hover and press feedback, entrances and exits, modals, toasts, menus, loading and skeleton states, staggered reveals, page or view transitions — so motion stays refined and purposeful, not decorative. Covers CSS, Web Animations, and React timing/easing. Pair with the motion skill for motion/react API specifics.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

animate

無料

Build an animation from scratch, making the decisions in the order that determines whether it feels right — should it animate at all, what purpose, which tool, which properties, which curve and duration, how it interrupts, how it exits. Writes the implementation. Use when asked to animate something, add motion, make a component feel alive, or build a transition. For critiquing existing motion use review-animations; for auditing a whole codebase use improve-animations. Only runs when explicitly invoked; it does not trigger on its own.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

Build animations for Expo and React Native only, using Reanimated, Gesture Handler, Expo Router, and expo-haptics. Use when the target runtime is an Expo or React Native app. Do not use it for Core Next.js web motion; use `animate` for web. Only runs when explicitly invoked; it does not trigger on its own.

日本語の概要は準備中です。原文の説明を表示しています。

Asymmetric-al/core3812026年10月12日 更新

Asymmetric-al のスキルをすべて見る

このスキルの問題を報告する