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

@julr/adonisjs-inngest

v1.0.0

Published

AdonisJS integration for Inngest workflows

Readme

AdonisJS Inngest

Small wrapper package to integrate Inngest with AdonisJS applications. Build reliable, type-safe background workflows using Inngest's powerful step functions.

Installation

Install the package from npm registry as follows:

npm i @julr/adonisjs-inngest inngest

Next, configure the package by running the following command:

node ace configure @julr/adonisjs-inngest

Local Development

To develop with Inngest, you need to run the Inngest Dev Server alongside your AdonisJS application:

npx inngest-cli@latest dev

This starts the Inngest dashboard at http://localhost:8288 where you can view and debug your workflows.

Configuration

The configuration is stored inside the config/inngest.ts file. You can define event schemas for type safety and register your workflows:

import vine from '@vinejs/vine'
import type { Inngest } from 'inngest'
import { EventSchemas } from 'inngest'
import app from '@adonisjs/core/services/app'
import { defineConfig, defineVineValidator, ServeStrategy } from '@julr/adonisjs-inngest'

const config = defineConfig({
  id: app.appName,
  isDev: app.inDev,
  connectionStrategy: new ServeStrategy({ servePath: '/api/inngest' }),
  schemas: new EventSchemas().fromSchema({
    'user/user.created': defineVineValidator({
      id: vine.string().uuid(),
      email: vine.string().email(),
    }),
    'order/payment.completed': defineVineValidator({
      orderId: vine.string(),
      amount: vine.number(),
    }),
  }),
  workflows: [
    () => import('#app/workflows/welcome_user_workflow'),
    () => import('#app/workflows/process_payment_workflow'),
  ],
})

export default config

declare module '@julr/adonisjs-inngest/types' {
  interface InngestTypings {
    client: Inngest<typeof config>
  }
}

Configuration options

  • id: Unique identifier for your Inngest app (usually your app name)
  • isDev: Development mode flag, automatically set based on your AdonisJS environment
  • connectionStrategy: How to connect to Inngest (see Connection Strategies section)
  • schemas: Event schemas for type safety using VineJS validators (or any standard schemas compatible library)
  • workflows: Array of workflow imports to register

Creating workflows

You can create a new workflow using the Ace command:

node ace make:workflow WelcomeUser

This will create a new workflow class in app/workflows/welcome_user_workflow.ts:

import { inject } from '@adonisjs/core'
import mail from '@adonisjs/mail/services/main'
import type { Inngest } from '@julr/adonisjs-inngest/types'
import { defineOptions, defineTrigger } from '@julr/adonisjs-inngest'

@inject()
export default class WelcomeUserWorkflow implements Inngest.Workflow {
  options = defineOptions({
    id: 'welcome-user',
    concurrency: 5,
  })

  trigger = defineTrigger({
    event: 'user/user.created',
  })

  async handler({ event, step }: Inngest.Context<WelcomeUserWorkflow>) {
    // Send welcome email immediately
    await step.run('send-welcome-email', async () => {
      await mail.send((message) => {
        message
          .to(event.data.email)
          .subject('Welcome!')
          .htmlView('emails/welcome', { user: event.data })
      })
    })

    // Wait 3 days before sending follow-up
    await step.sleep('wait-3-days', '3d')

    // Send follow-up email
    await step.run('send-followup-email', async () => {
      await mail.send((message) => {
        message
          .to(event.data.email)
          .subject('How are you doing?')
          .htmlView('emails/followup', { user: event.data })
      })
    })

    return { emailsSent: 2 }
  }

  onFailure({ event, error }: Inngest.Context<WelcomeUserWorkflow>) {
    logger.error('Welcome workflow failed for user:', event.data.id, error)
  }
}

Workflow structure

Class-based approach

Workflows are defined as classes implementing the Inngest.Workflow interface. This allows you to use AdonisJS's dependency injection system with the @inject() decorator.

Required properties

  • options: Configuration object with workflow ID and other Inngest options
  • trigger: Event trigger configuration (event name or cron schedule)
  • handler: Main workflow function that receives the Inngest context

Optional properties

  • onFailure: Called when the workflow fails, useful for error handling and cleanup

step.invoke

This package extends Inngest's step.invoke to work seamlessly with workflow classes:

export default class ProcessOrderWorkflow implements Inngest.Workflow {
  async handler({ step }: Inngest.Context<ProcessOrderWorkflow>) {
    // Invoke another workflow using the class (type-safe)
    await step.invoke('send-confirmation', {
      workflow: SendEmailWorkflow, // Pass the workflow class
      data: { // Automatically typed based on SendEmailWorkflow's trigger
        orderId: event.data.id, 
        email: event.data.email 
      }
    })
  }
}

The data object is automatically typed based on the target workflow's trigger event schema, providing full type safety across workflow boundaries.

See the official documentation for more details on step.invoke.

Triggering workflows

From your application

You can trigger workflows by sending events using the Inngest service:

import inngest from '@julr/adonisjs-inngest/services/main'

export default class UsersController {
  async store({ request }: HttpContext) {
    const user = await User.create(request.body())

    await inngest.send({
      name: 'user/user.created',
      data: { id: user.id, email: user.email, },
    })

    return user
  }
}

Scheduled workflows

You can also create cron-based workflows:

export default class DailyReportWorkflow implements Inngest.Workflow {
  options = defineOptions({
    id: 'daily-report',
  })

  trigger = defineTrigger({
    cron: '0 9 * * *', // Every day at 9 AM
  })

  async handler({ step }: Inngest.Context<DailyReportWorkflow>) {
    // Generate and send daily report
  }
}

Connection Strategies

This package supports two connection strategies for communicating with Inngest:

ServeStrategy (HTTP)

Uses HTTP endpoints to receive events from Inngest. This is the traditional approach and works well for most use cases:

import { ServeStrategy } from '@julr/adonisjs-inngest'

const config = defineConfig({
  connectionStrategy: new ServeStrategy({
    servePath: '/api/inngest', // HTTP endpoint path
    serveHost: 'localhost:3333', // Your app's host
  }),
})

ConnectStrategy (WebSocket)

Uses persistent WebSocket connections for lower latency and better scaling:

import { ConnectStrategy } from '@julr/adonisjs-inngest'

const config = defineConfig({
  connectionStrategy: new ConnectStrategy({
    // Optional connect-specific options
  }),
})

When to use each:

  • ServeStrategy: Simple setups, development, traditional deployments
  • ConnectStrategy: Production environments, container deployments, need for lower latency

For more details on the differences, see the Inngest documentation on serve vs connect methods.

Type Safety

The package provides full type safety for your events when you define schemas in your configuration. The event data will be automatically typed based on your VineJS schemas:

// event.data is automatically typed as { id: string, email: string }
async handler({ event }: Inngest.Context<WelcomeUserWorkflow>) {
  console.log(event.data.id) // ✅ TypeScript knows this is a string
  console.log(event.data.invalidProp) // ❌ TypeScript error
}

Learn more

This package provides AdonisJS-specific features on top of Inngest. For comprehensive documentation about Inngest's capabilities, step functions, retry logic, and advanced features, visit the official Inngest documentation.

License

MIT