npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@contract-kit/provider-inngest

v0.1.2

Published

Inngest provider for contract-kit - adds inngest port for background jobs and events

Readme

@contract-kit/provider-inngest

Inngest provider for contract-kit that extends your application ports with background job and event capabilities using Inngest.

Installation

npm install @contract-kit/provider-inngest inngest
# or
bun add @contract-kit/provider-inngest inngest

TypeScript Requirements

This package requires TypeScript 5.0 or higher for proper type inference.

Usage

Basic Setup

import { createServer } from "@contract-kit/server";
import { inngestProvider } from "@contract-kit/provider-inngest";

// Set environment variables:
// INNGEST_APP_NAME=my-app (optional, defaults to "contract-kit-app")
// INNGEST_EVENT_KEY=your-event-key (optional, required for Inngest Cloud)

const app = createServer({
  ports: basePorts,
  providers: [inngestProvider],
  createContext: ({ ports }) => ({
    ports,
    // ... other context
  }),
  routes: [
    // ... your routes
  ],
});

Sending Events in Use Cases

Once the provider is registered, your ports will include an inngest property:

// In your use case
async function inviteUser(ctx: AppCtx, input: InviteUserInput) {
  // Create the invite
  const invite = await ctx.ports.db.invites.create({
    inviterId: ctx.userId!,
    inviteeEmail: input.email,
  });

  // Send an event to trigger background job
  await ctx.ports.inngest.send({
    name: "user.invited",
    data: {
      inviterId: ctx.userId!,
      inviteeEmail: input.email,
      inviteId: invite.id,
    },
  });

  return invite;
}

Configuration

The Inngest provider reads configuration from environment variables with the INNGEST_ prefix:

| Variable | Required | Description | Default | |----------|----------|-------------|---------| | INNGEST_APP_NAME | No | Friendly application name shown in Inngest | "contract-kit-app" | | INNGEST_EVENT_KEY | No | Event key / signing key for Inngest Cloud | - |

Note: INNGEST_EVENT_KEY is required when using Inngest Cloud for production deployments.

Inngest Port API

The provider extends your ports with the following inngest interface:

send<TData>(args: { name: string; data: TData }): Promise<void>

Send an event to Inngest.

await ctx.ports.inngest.send({
  name: "user.invited",
  data: {
    inviterId: ctx.userId!,
    inviteeEmail: input.email,
    inviteId: createdInvite.id,
  },
});

client: Inngest

Access the underlying Inngest client for advanced operations like defining functions.

// Define Inngest functions using the client directly
const myFunction = ctx.ports.inngest.client.createFunction(
  { id: "my-function" },
  { event: "user.invited" },
  async ({ event, step }) => {
    // Your function logic
  }
);

TypeScript Support

To get proper type inference for the inngest port, extend your ports type:

import type { InngestPort } from "@contract-kit/provider-inngest";

// Your base ports
const basePorts = definePorts({
  db: dbAdapter,
});

// After using inngestProvider, your ports will have this shape:
type AppPorts = typeof basePorts & {
  inngest: InngestPort;
};

Wiring Domain Events → Inngest Jobs

This provider does NOT automatically subscribe to domain events. This is intentional to keep the provider generic and reusable.

To wire domain events to Inngest jobs, create a separate jobs provider in your application:

// app/providers/jobs.ts
import { createProvider } from "@contract-kit/ports";
import type { AppPorts } from "@/lib/ports";

export const jobsProvider = createProvider<AppPorts, never>({
  name: "jobs",

  async register({ ports }) {
    // Define your job-specific methods
    ports.extend("jobs", {
      enqueueInviteEmail: async (event) => {
        await ports.inngest.send({ 
          name: "user.invited", 
          data: event 
        });
      },
    });
  },

  async onAppStart({ ports }) {
    // Subscribe to domain events and enqueue jobs
    ports.eventBus.subscribe("user.invited", async (event) => {
      await ports.jobs.enqueueInviteEmail(event);
    });
  },
});

Then use it in your app:

const app = createServer({
  ports: basePorts,
  providers: [
    eventBusProvider,
    inngestProvider,
    jobsProvider, // Wire domain events → Inngest
  ],
  // ...
});

This pattern clearly separates:

  • Framework-level provider (inngestProvider) → Inngest integration
  • App-level provider (jobsProvider) → Business job logic

Inngest Functions

Inngest functions (the handlers that process events) should be defined separately from your Contract Kit application, typically in a separate API route or serverless function:

// app/api/inngest/route.ts (Next.js App Router example)
import { serve } from "inngest/next";
import { inngest } from "@/lib/inngest"; // Your Inngest client

// Define your functions
const sendInviteEmail = inngest.createFunction(
  { id: "send-invite-email" },
  { event: "user.invited" },
  async ({ event, step }) => {
    await step.run("send-email", async () => {
      // Send email logic
    });
  }
);

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

Lifecycle

The Inngest provider:

  1. During register:
    • Creates Inngest client
    • Adds the inngest port
  2. No cleanup needed: Inngest client doesn't require explicit shutdown

Error Handling

The provider will throw errors in these cases:

  • Missing required configuration (though all fields have defaults or are optional)
  • Invalid configuration values

Make sure to handle these during application startup.

Local Development

For local development, you can run the Inngest Dev Server:

npx inngest-cli@latest dev

This provides a local UI at http://localhost:8288 where you can:

  • View events
  • Trigger functions
  • Debug execution

License

MIT