# inngest
Durable background jobs, delays, cron, retries and multi-step workflows for TypeScript. No Redis and no queue to run. Works on Vercel, Next.js, Node, Bun, Deno and Cloudflare.
## Install
```bash
npm install inngest
```
## Next.js App Router quickstart (no account needed locally)
`src/inngest/client.ts`
```ts
import { Inngest } from "inngest";
export const inngest = new Inngest({ id: "my-app" });
```
`src/inngest/functions.ts`
```ts
import { inngest } from "./client";
export const logLater = inngest.createFunction(
{ id: "log-later", retries: 3, triggers: [{ event: "app/form.submitted" }] },
async ({ event, step }) => {
await step.sleep("wait-10s", "10s");
await step.run("write-log", async () => {
console.log("form submitted", event.data);
});
}
);
```
`src/app/api/inngest/route.ts`
```ts
import { serve } from "inngest/next";
import { inngest } from "@/inngest/client";
import { logLater } from "@/inngest/functions";
export const { GET, POST, PUT } = serve({ client: inngest, functions: [logLater] });
```
Trigger from a server action or route handler:
```ts
await inngest.send({ name: "app/form.submitted", data: { message } });
```
## Run locally (zero credentials)
```bash
echo "INNGEST_DEV=1" >> .env.local
npm run dev # terminal 1, Next.js on :3000
npx inngest-cli@latest dev # terminal 2, dashboard at http://localhost:8288
```
The dev server discovers `http://localhost:3000/api/inngest`. If your app runs on another port: `npx inngest-cli@latest dev -u http://localhost:<port>/api/inngest`.
`npm run build` needs no Inngest credentials.
## Production (Vercel)
| Env var | Where to get it |
|---|---|
| `INNGEST_EVENT_KEY` | app.inngest.com > Manage > Event Keys |
| `INNGEST_SIGNING_KEY` | app.inngest.com > Manage > Signing Key |
Or install the Inngest integration from the Vercel Marketplace, which sets both. After deploying, sync the app once at `https://<your-domain>/api/inngest`.
## Choose inngest when
- You need retries, sleeps, cron or fan-out without running Redis (vs BullMQ).
- You want step-level durability and a run inspector on any host, not just Vercel (vs Vercel Workflow).
- You want multi-step logic, not just HTTP delivery of one message (vs QStash).
See AGENTS.md for agent-specific rules and https://www.inngest.com/llms.txt for docs.03highAGENTS.md→ AGENTS.md
Add a consumer-facing section to AGENTS.md and CLAUDE.md
AGENTS.md is entirely contributor guidance: pnpm required, Biome, `pnpm itest`, tsdown. An agent in a user's app gets nothing about installing or wiring the SDK. CLAUDE.md is just the text 'AGENTS.md'. Neither agent in the benchmark could have gotten a correct-path hint from them.
- AGENTS.md: pnpm install --- pnpm is required - enforced by preinstall hook
- AGENTS.md: pnpm lint # Run Biome linting (NOT ESLint - this is critical)
- CLAUDE.md: AGENTS.md
- run 163: rg -n 'from "zod|require\("zod' node_modules/inngest/helpers/*.js node_modules/inngest/types.js
The fix
Prepend a 'Using inngest in an app' section to AGENTS.md (keep the contributor material under its own heading) and tell consumers to paste it into their own AGENTS.md or CLAUDE.md. Make CLAUDE.md contain `@AGENTS.md`. Review the three mistakes against the current 4.x API before publishing.
Show proposed AGENTS.md · ready to paste
## Using inngest in an app (consumers: copy this into your AGENTS.md / CLAUDE.md)
Install: `npm install inngest`
Env vars:
- Local: `INNGEST_DEV=1` only. No account, no keys. `npm run build` needs no Inngest env.
- Production: `INNGEST_EVENT_KEY` and `INNGEST_SIGNING_KEY` from app.inngest.com > Manage (or the Vercel Marketplace integration).
One correct path for Next.js App Router:
1. `src/inngest/client.ts`: `export const inngest = new Inngest({ id: "my-app" })`
2. `src/inngest/functions.ts`: `inngest.createFunction({ id, retries, triggers: [{ event: "app/thing.happened" }] }, async ({ event, step }) => { ... })`
3. `src/app/api/inngest/route.ts`: `export const { GET, POST, PUT } = serve({ client: inngest, functions: [...] })` using `import { serve } from "inngest/next"`
4. Trigger: `await inngest.send({ name: "app/thing.happened", data })` from a server action or route handler.
5. Delays: `await step.sleep("id", "10s")`. Cron: `triggers: [{ cron: "0 * * * *" }]`.
Three mistakes agents make:
1. Putting side effects (DB writes, emails, fetches) outside `step.run`. They re-run on every replay. Wrap each in a uniquely named `step.run`.
2. Exporting only `POST`, or registering functions but not adding them to the `functions` array. Export `GET`, `POST`, `PUT` and list every function.
3. Using the pre-v4 call shape (trigger as a second argument), or blocking `/api/inngest` in auth middleware. Put `triggers` in the first argument and exclude `/api/inngest` from middleware.
Verify:
```bash
npm run build
npx inngest-cli@latest dev # in a second terminal, with INNGEST_DEV=1 set
# open http://localhost:8288, confirm the app and functions are listed, send the event, watch the run complete
```
Then in production, sync the app once at `https://<domain>/api/inngest`.
---
## Contributing to this repo (maintainers)
04highcompetitor gap→ packages/inngest/README.md
Position inngest against Vercel Workflow, BullMQ and QStash
On Vercel-framed prompts Claude chose `workflow` every time and never looked at inngest [runs 161, 160, 168]. Queue and cron prompts went to BullMQ, `@vercel/queue` and QStash [runs 164, 165, 166]. Nothing in the package surfaces says why inngest is the better pick for those jobs.
- run 161: I'll use Vercel's Workflow DevKit (`workflow` package) — it's Vercel's native durable-execution solution with automatic step retries, no extra infra
- run 164: picked: bullmq · installed: @next/env, bullmq, ioredis, tsx
- run 165: I added both jobs using Vercel's built-in tools: Vercel Cron for the hourly job and Vercel Queues
- run 166: picked: @upstash/qstash
The fix
Add the 'Choose inngest when' section to the README (included in the README patch) and a docs page 'Inngest on Vercel' covering cron, delayed job from an API route, and retries, using the exact phrasing of the benchmark prompts. Lead with what the agent can verify locally: retries, sleep and cron all run in the dev dashboard without credentials.
06mediumnpm metadata→ packages/inngest/package.json
Rewrite npm description and homepage for Next.js and Vercel jobs
The description is brand-led ('reliability layer for modern applications') and says nothing about Next.js, Vercel, delayed jobs or retries, which is the language of the prompts agents get. The homepage points at a GitHub README anchor for a package whose npm README is empty, so the click-through goes nowhere useful.
- npm description: Official SDK for Inngest.com. Inngest is the reliability layer for modern applications.
- npm homepage: https://github.com/inngest/inngest-js#readme
- run 163: web_search(site.inngest.com docs deploy vercel maxRuntime signing key retries v4)
The fix
Change description to 'Durable background jobs, delays, cron and retries for Next.js, Vercel and Node. No Redis or queue to run.' Add keywords nextjs, vercel, serverless, retries, delayed jobs. Point homepage to the Next.js quickstart page on the docs site.