Beignet API reference
    Preparing search index...

    Module @beignet/provider-inngest

    @beignet/provider-inngest

    Inngest-backed JobDispatcherPort provider for Beignet applications.

    The provider installs the app-facing ctx.ports.jobs dispatcher for durable background jobs using Inngest and exposes ctx.ports.inngest only as an escape hatch for raw Inngest access.

    bun add @beignet/provider-inngest @beignet/core inngest
    
    import { createNextServer } from "@beignet/next";
    import { definePorts } from "@beignet/core/ports";
    import { inngestProvider } from "@beignet/provider-inngest";
    import { routes } from "@/server/routes";

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

    const appPorts = definePorts({});

    export const server = await createNextServer({
    ports: appPorts,
    providers: [inngestProvider],
    createContext: ({ ports }) => ({
    ports,
    }),
    routes,
    });

    Once the provider is registered, your ports include:

    • jobs: the canonical JobDispatcherPort for app code.
    • inngest: the raw Inngest escape hatch for advanced usage.

    Define jobs with @beignet/core/jobs, then dispatch them through ctx.ports.jobs:

    import { createJobHandlers } from "@beignet/core/jobs";
    import { z } from "zod";

    const jobs = createJobHandlers<AppCtx>();

    export const SendInviteEmailJob = jobs.defineJob("mail.invite.send", {
    payload: z.object({
    inviteId: z.string(),
    inviteeEmail: z.string().email(),
    }),
    retry: {
    attempts: 3,
    },
    async handle({ payload, ctx }) {
    await ctx.ports.mailer.send({
    to: payload.inviteeEmail,
    subject: "You were invited",
    text: `Invite id: ${payload.inviteId}`,
    });
    },
    });

    async function inviteUser(ctx: AppCtx, input: InviteUserInput) {
    const invite = await ctx.ports.db.invites.create({
    inviterId: ctx.actor.id,
    inviteeEmail: input.email,
    });

    await ctx.ports.jobs.dispatch(SendInviteEmailJob, {
    inviteId: invite.id,
    inviteeEmail: input.email,
    });

    return invite;
    }

    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 "beignet-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.

    The jobs port is the recommended application API. It validates and parses the job payload with the job definition before sending an Inngest event using the job name.

    await ctx.ports.jobs.dispatch(SendInviteEmailJob, {
    inviteId: invite.id,
    inviteeEmail: input.email,
    });

    The inngest port is an escape hatch for direct Inngest usage.

    Send a raw event to Inngest. Prefer ctx.ports.jobs.dispatch(...) for first-class Beignet jobs.

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

    Access the underlying Inngest client for advanced operations.

    // 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
    }
    );

    When @beignet/devtools is registered before this provider, calls to ctx.ports.jobs.dispatch(...) and ctx.ports.inngest.send(...) are recorded automatically under the jobs watcher. Successful enqueues are recorded as scheduled; failed enqueues are recorded as failed with schedule-phase error details.

    Pass an instrumentation target to createInngestJobFunction(...) to record worker execution as started, completed, and failed events:

    const sendInviteEmail = createInngestJobFunction({
    client: inngest,
    job: SendInviteEmailJob,
    ctx: () => createBackgroundContext(),
    instrumentation: appPorts.devtools,
    });

    To get proper type inference, include both provider-contributed ports in your app ports type:

    import { definePorts } from "@beignet/core/ports";
    import type { JobDispatcherPort } from "@beignet/core/ports";
    import type { InngestPort } from "@beignet/provider-inngest";

    // Your base ports, if any
    const basePorts = definePorts({});

    type AppPorts = typeof basePorts & {
    jobs: JobDispatcherPort;
    inngest: InngestPort;
    };

    This provider does NOT automatically subscribe to domain events. That is intentional: events are facts that happened, while jobs are explicit work to do.

    To wire a domain event to a durable job, register a listener in your application and dispatch the job from the listener:

    // features/users/listeners.ts
    import { createEventHandlers } from "@beignet/core/events";
    import { UserInvited } from "@/features/users/domain/events";
    import { SendInviteEmailJob } from "@/features/users/jobs";
    import type { AppCtx } from "@/app-context";

    const events = createEventHandlers<AppCtx>();

    export const sendInviteEmail = events.defineListener(UserInvited, {
    name: "mail.send-invite-email",
    async handle({ payload, ctx }) {
    await ctx.ports.jobs.dispatch(SendInviteEmailJob, {
    inviteId: payload.inviteId,
    inviteeEmail: payload.inviteeEmail,
    });
    },
    });

    Register that listener against your event bus during infrastructure startup. In tests, use createInlineJobDispatcher(...) from @beignet/core/jobs; in production, install inngestProvider.

    Use createInngestJobFunction(...) to turn a first-class Beignet job into an Inngest function. The helper subscribes to job.name, validates incoming event data with parseJobPayload, and then calls job.handle(...).

    If the job defines retry.attempts, the helper maps it to Inngest's function-level retries option. Inngest supports integer values from 0 to 20; values outside that range throw during function creation.

    Define functions separately from your Beignet server, usually in a serverless function or route handler:

    // app/api/inngest/route.ts (Next.js App Router example)
    import { createInngestJobFunction } from "@beignet/provider-inngest";
    import { serve } from "inngest/next";
    import { inngest } from "@/infra/inngest";
    import { SendInviteEmailJob } from "@/features/users/jobs";
    import { createBackgroundContext } from "@/infra/background-context";

    const sendInviteEmail = createInngestJobFunction({
    client: inngest,
    job: SendInviteEmailJob,
    ctx: () => createBackgroundContext(),
    });

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

    createBackgroundContext() is application-owned. Put it near your infrastructure wiring and return the ports, logger, auth assumptions, and devtools context your background workers need.

    The Inngest provider:

    1. During setup:
      • Creates Inngest client
      • Returns the jobs port
      • Returns the inngest escape hatch port
    2. No cleanup needed: Inngest client doesn't require explicit shutdown

    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.

    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

    MIT

    Interfaces

    CreateInngestJobFunctionOptions
    InngestJobDispatcherOptions
    InngestJobFunctionContextArgs
    InngestPort

    Type Aliases

    InngestConfig
    InngestFunctionRetryAttempts
    InngestJobFunctionContext
    InngestJobFunctionInstrumentation

    Variables

    inngestProvider

    Functions

    createInngestJobDispatcher
    createInngestJobFunction