Local Development with the Inngest Dev Server
By now you've used the Dev Server — you've watched runs appear in the Runs tab, clicked Invoke to trigger functions, and spotted a failing step in the timeline. But you've been using it as a passive observer.
This article goes deeper. The Dev Server is a fully-featured local version of the Inngest Platform. Everything you do here — the dashboard, the event log, the run traces, the replay button — is the same system you'll use in production. Getting fluent with it now means you'll debug production issues in minutes instead of hours.
Let's explore every corner of it.
Quick Reference
Start the Dev Server:
npx --ignore-scripts=false inngest-cli@latest dev -u http://localhost:3000/api/inngest
Dashboard URL: http://localhost:8288
Four ways to trigger a function:
- Invoke button in the Functions tab (best for isolated testing)
- "Test Event" button — top right corner (best for testing event payloads)
inngest.send()from your app code (most production-realistic)curltohttp://localhost:8288/e/YOUR_KEY(best for automation and CI)
No account required. The Dev Server runs entirely on your machine. No API key, no internet connection needed for local development.
Open source. The Dev Server is the same binary that powers Inngest's self-hosted offering — available on GitHub.
What You Need to Know First
Required reading:
- Your First Inngest Function — basic Dev Server setup
You should be comfortable with:
- Starting the Dev Server and connecting it to your app
- Watching runs appear in the Runs tab
- The serve endpoint (
/api/inngest) and why it exists
What We'll Cover in This Article
By the end of this guide, you'll understand:
- Every tab in the Dev Server dashboard and what it's for
- All four methods for sending test events
- How to read a run trace and what each status means
- How to replay a failed run after fixing a bug
- Auto-discovery — how it works, when to disable it, and how to add apps manually
- The
inngest.jsonconfiguration file for team-shared settings - CLI flags for advanced Dev Server configuration
- Running the Dev Server with Docker (for Docker-based teams)
- The MCP integration — connecting AI coding assistants to the Dev Server
- The SDK debug endpoint — a hidden diagnostic tool
What We'll Explain Along the Way
- What "polling" means in the context of how the Dev Server loads functions
- What a run status means: Running, Completed, Failed, Cancelled, Sleeping
- How replay differs from a new function run
Part 1: The Dashboard — A Tab-by-Tab Tour
Open http://localhost:8288 with both your app and the Dev Server running. You'll see five tabs in the left navigation. Let's walk through each.
Apps
The Apps tab shows every app the Dev Server has connected to. An "app" is your serve endpoint — one entry per /api/inngest URL you've added.
For each app, you'll see:
- The app ID (the string you set in
new Inngest({ id: "..." })) - The URL of the serve endpoint
- The number of functions registered
- The sync status — whether the Dev Server successfully read the latest function list from your app
This is your first debugging stop if functions aren't appearing. If the app shows a sync error (red indicator), your serve endpoint isn't reachable or isn't returning valid data. Click the app entry to see the raw error.
Adding an app manually: If auto-discovery hasn't found your app, click "Add App" in the top right, paste your serve URL (http://localhost:3000/api/inngest), and hit Sync.
Functions
The Functions tab lists every function registered across all connected apps. For each function you'll see:
- The function ID (the
idyou set increateFunction) - The trigger: event name or cron expression
- The app it belongs to
- The last time it ran
Click any function to see its detail page, which shows the full function configuration, trigger details, and a history of recent runs for that function specifically.
The Invoke button lives here. Click Invoke on any function to open a modal where you paste a JSON event payload and trigger the function immediately — no need to write app code, no need to wait for an event. This is your fastest iteration loop when building a new function.
When to use Invoke:
→ You're building a new function and want to test it immediately
→ You want to test a specific edge case (malformed data, missing fields)
→ You're developing a cron function and can't wait for the schedule
→ You want to isolate one function without triggering others
For cron functions, the Invoke modal lets you trigger the function on demand. Since cron functions receive no event, the payload modal may be empty or ask for optional override data.
Runs
The Runs tab is where you spend most of your time. Every function execution — from any app, any trigger — appears here in reverse chronological order.
Each run entry shows:
- Function name and ID
- Status badge:
Running,Completed,Failed,Cancelled,Sleeping - Start time and duration
- The triggering event name (or
cronfor scheduled functions)
Filtering runs: Use the search bar and status filters to narrow down runs by function name, status, or time range. This is essential once you have many functions running simultaneously.
Status meanings:
| Status | What it means |
|---|---|
Running | Function is currently executing a step |
Sleeping | Function hit step.sleep() or step.sleepUntil() — paused, waiting |
Waiting | Function hit step.waitForEvent() — paused, listening for an event |
Completed | All steps ran successfully, function returned a result |
Failed | A step exhausted all retries — function has given up |
Cancelled | Function was cancelled (by cancelOn or manually) |
Run Detail View
Click any run to open its detail view — this is the most powerful part of the Dev Server.
The detail view has three sections:
Timeline — A visual trace of every step, showing:
- Step name and ID
- Status of each attempt (success, fail, retry)
- Duration of each attempt
- The step's return value (expandable JSON)
This is where you debug. When a step fails, click it to see the full error message, the stack trace, and exactly which attempt failed. You can see every retry attempt in sequence.
Event payload — The full JSON of the triggering event. Useful for verifying that the data your function received is what you actually sent.
Function output — The return value of the entire function (what you returned from the handler).
Trigger — Shows whether the function was triggered by an event or a cron schedule, and provides a link to the triggering event in the event log.
Events
The Events tab is a chronological log of every event received by the Dev Server — from your app code, from the "Test Event" button, from curl, from anywhere.
Each event entry shows:
- Event name
- Timestamp
- The full JSON payload (expandable)
- Which function runs it triggered (links to those runs)
This tab answers the question "did my event actually arrive?" — useful when you inngest.send() from your app and don't see a run appear. Check here first: if the event isn't in the log, it never reached the Dev Server. If it's in the log but didn't trigger a function, your function trigger expression may not match the event name.
Part 2: Four Ways to Send Test Events
Method 1: Invoke Button (recommended for isolated function testing)
Location: Functions tab → select a function → click "Invoke"
The Invoke button calls your function directly without sending an event through the normal event pipeline. It bypasses event-level deduplication and lets you provide a custom payload in a modal JSON editor.
This is the fastest way to test a function in isolation:
// Example payload for "user/account.created" trigger
{
"data": {
"userId": "usr_test_001",
"email": "test@example.com",
"name": "Test User",
"plan": "free"
}
}
Click "Invoke Function" and the run appears in the Runs tab within seconds.
Method 2: Test Event Button (recommended for testing event payloads)
Location: Top-right corner of the Dev Server UI → "Test Event"
This sends an actual event through the full event pipeline — it appears in the Events tab and triggers every function registered for that event name. Unlike the Invoke button (which calls one function directly), this mirrors what happens in production when inngest.send() is called.
Use this when:
- You want to trigger a fan-out (all functions listening to the event)
- You want to verify your event appears in the Events log
- You want to test event-level deduplication behaviour
// Full event format (the "Test Event" modal expects this shape)
{
"name": "user/account.created",
"data": {
"userId": "usr_test_001",
"email": "test@example.com",
"name": "Test User"
}
}
Method 3: inngest.send() from your app code (most production-realistic)
The most realistic test: trigger events the same way production will. Call inngest.send() from an API route, trigger it with curl or Postman, and watch the function run.
# Trigger your API route
curl -X POST http://localhost:3000/api/signup \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "name": "Test User"}'
Your route calls inngest.send(), the event goes to the Dev Server, functions run. This is the test method that most closely mirrors production — same code paths, same timing, same data flow.
Method 4: Direct HTTP to the Dev Server event API (best for automation and CI)
Send events directly to the Dev Server's HTTP event endpoint without going through your app at all:
# Send an event directly to the Dev Server
# Use any string as the event key locally — the Dev Server doesn't validate keys
curl -X POST "http://localhost:8288/e/test-key" \
-H "Content-Type: application/json" \
-d '{
"name": "user/account.created",
"data": {
"userId": "usr_test_001",
"email": "test@example.com",
"name": "Test User"
}
}'
This is ideal for:
- Integration tests that need to fire events programmatically
- CI pipelines that run end-to-end tests against the Dev Server
- Sending events from a language or environment that doesn't have the Inngest SDK
The Dev Server doesn't validate event keys locally, so any string works as the key in the URL.
Part 3: Reading Run Traces — The Debug Workflow
The run detail timeline is your primary debugging tool. Let's walk through how to read it for different scenarios.
Scenario A: A step is failing and retrying
You see a run with status Failed (or Running with retries in progress). Click the run.
In the timeline, each failed step shows:
Step: "send-welcome-email"
├── Attempt 1: ❌ Failed — Error: Connection timeout (ETIMEDOUT)
│ Duration: 30,000ms
│ Error: connect ETIMEDOUT 198.51.100.1:587
│
├── Attempt 2: ❌ Failed — Error: Connection timeout (ETIMEDOUT)
│ Duration: 30,000ms
│
└── Attempt 3: ❌ Failed — exhausted retries
The function run is now marked "Failed"
Click any attempt to expand the full error object, including the stack trace from your code. This tells you:
- The exact line in your code where the error was thrown
- The error type (network error, database error, type error, etc.)
- The error message
What to do: Fix the bug in your code, save the file (your dev server hot-reloads), then replay the run (see Part 4).
Scenario B: A function is stuck in "Sleeping" or "Waiting"
The run shows Sleeping — it hit a step.sleep() and is waiting for a duration. You can see in the timeline:
Step: "send-welcome-email" ✅ Completed
Step: "wait-3-days" 💤 Sleeping until 2025-06-15T09:00:00Z
The Dev Server shows the exact timestamp when the function will resume. You can't fast-forward a sleep in the Dev Server (it respects the actual duration), but you can cancel the run and create a new one with a shorter sleep duration if you need to test the code that follows.
For Waiting (from step.waitForEvent()), the timeline shows which event name and match condition it's waiting for. Send that event via the Test Event button or inngest.send() to resume it immediately.
Scenario C: The run completed but the output looks wrong
Click the completed run. Check:
-
Event payload — Was the input data what you expected? If the event payload is malformed, the problem is upstream in how you're calling
inngest.send(). -
Step outputs — Expand each step's return value. Does each step return what you expected? Follow the data through the steps to find where it diverged from expectation.
-
Function output — What did the handler return? Is the final return value correct?
This step-by-step data inspection is only possible because every step's input and output is saved by Inngest — you can trace data through the entire execution at any point in time.
Part 4: Replaying Failed Runs
After fixing a bug, you want to re-run the exact same function with the exact same event data — not set up a new test. This is what Replay does.
Open any Failed run in the Dev Server. In the top right of the run detail page, click the Replay button.
The Dev Server creates a new run using the same original event payload. The new run starts fresh — all steps execute again (there's no memoisation between runs, only within a run). Your fixed code runs against the original data.
Original run (before fix):
Event: { userId: "usr_001", email: "test@example.com" }
Step 1: ✅ Completed
Step 2: ❌ Failed — TypeError: Cannot read property 'id' of undefined
You fix the bug in your code.
Replayed run (after fix):
Event: { userId: "usr_001", email: "test@example.com" } ← same original event
Step 1: ✅ Completed
Step 2: ✅ Completed ← now works with your fix
Step 3: ✅ Completed
Function: ✅ Completed
Replay vs Invoke: Replay uses the exact original event. Invoke requires you to provide a new payload. Use Replay when you've fixed a bug and want to verify the fix works on the data that actually failed. Use Invoke when you want to test a new scenario.
Part 5: Auto-Discovery
The Dev Server scans common ports and paths to find your app automatically. This means you often don't need the -u flag — the Dev Server finds your app on its own.
The Dev Server does auto-discovery, which scans popular ports and endpoints like /api/inngest and /.netlify/functions/inngest. It checks ports 3000, 3001, 8000, 8080, and others in sequence.
When auto-discovery causes problems
Duplicate runs: If your app is running on port 3000 and you also pass -u http://localhost:3000/api/inngest, the Dev Server connects to your app twice — once via auto-discovery and once via the manual URL. Events trigger two sets of function runs.
Fix: Disable auto-discovery when using the -u flag:
npx --ignore-scripts=false inngest-cli@latest dev \
--no-discovery \
-u http://localhost:3000/api/inngest
Multiple apps on different ports: If you're running a microservices setup with multiple apps on different ports, auto-discovery may find some but not all. Add the missing ones manually via the Apps tab or with multiple -u flags:
npx --ignore-scripts=false inngest-cli@latest dev \
--no-discovery \
-u http://localhost:3000/api/inngest \
-u http://localhost:3001/api/inngest \
-u http://localhost:4000/api/inngest
Part 6: The inngest.json Configuration File
For teams where everyone needs the same Dev Server configuration, create an inngest.json file in your project root. The Dev Server reads this automatically when started from the same directory.
{
"sdk_url": "http://localhost:3000/api/inngest"
}
This is the equivalent of always passing -u http://localhost:3000/api/inngest — anyone who runs npx inngest-cli dev in this directory gets the same setup without needing to remember the flag.
For multi-app setups, list multiple URLs:
{
"sdk_url": [
"http://localhost:3000/api/inngest",
"http://localhost:3001/api/inngest"
]
}
Commit inngest.json to your repository so the whole team gets consistent local development configuration. There's no sensitive data in this file — it's just URLs.
You can also name the file inngest.yml or inngest.yaml if you prefer YAML format:
sdk_url: http://localhost:3000/api/inngest
Part 7: CLI Flags Reference
The full set of flags for inngest-cli dev:
npx --ignore-scripts=false inngest-cli@latest dev [flags]
| Flag | What it does |
|---|---|
-u <url> | Connect to a specific serve endpoint |
--no-discovery | Disable auto-discovery of apps on common ports |
--port <n> | Run the Dev Server on a different port (default: 8288) |
--log-level <level> | Set log verbosity: trace, debug, info, warn, error |
--no-poll | Disable automatic polling for function changes (manual sync only) |
Non-default port
If port 8288 is already in use on your machine:
npx --ignore-scripts=false inngest-cli@latest dev --port 9000
# Dev Server now at http://localhost:9000
If you change the port, update INNGEST_DEV handling — you may need to set the Dev Server URL explicitly in your environment:
# Tell the SDK where the Dev Server is (if it's not on the default port)
INNGEST_BASE_URL=http://localhost:9000 npm run dev
Part 8: Running with Docker
If your team uses Docker for local development, the Dev Server has first-class Docker support. As described in Inngest's self-hosting announcement, the same binary that powers the Dev Server also powers Inngest's self-hosted option.
Standalone Docker container
docker run --rm -p 8288:8288 \
inngest/inngest \
inngest dev -u http://host.docker.internal:3000/api/inngest
host.docker.internal is the hostname Docker uses to refer to your host machine's localhost from inside a container. Replace 3000 with your app's port.
Docker Compose
For teams using docker-compose.yml:
version: "3.8"
services:
app:
build: .
ports:
- "3000:3000"
environment:
- INNGEST_DEV=1
- INNGEST_BASE_URL=http://inngest:8288
inngest:
image: inngest/inngest
command: inngest dev --no-discovery -u http://app:3000/api/inngest
ports:
- "8288:8288"
depends_on:
- app
Key points in this setup:
- The app uses
INNGEST_BASE_URL=http://inngest:8288to point the SDK at the Inngest container (notlocalhost) - The Inngest container uses
http://app:3000/api/inngestto point at the app container (notlocalhost) --no-discoveryprevents the Inngest container from scanning its own internal ports
Part 9: The SDK Debug Endpoint
The Inngest SDK exposes a debug endpoint at GET /api/inngest that returns diagnostic information about your registered functions. This is the same endpoint the Dev Server calls to discover your functions.
curl http://localhost:3000/api/inngest
The response looks like:
{
"message": "Inngest endpoint configured correctly.",
"hasSigningKey": false,
"hasEventKey": false,
"functionsFound": 4,
"functions": [
{
"id": "handle-user-signup",
"name": "handle-user-signup",
"triggers": [{ "event": "user/account.created" }],
"steps": {}
},
{
"id": "send-weekly-digest",
"name": "send-weekly-digest",
"triggers": [{ "cron": "0 9 * * FRI" }],
"steps": {}
}
]
}
This is your diagnostic tool when the Dev Server isn't finding your functions:
# Does the endpoint exist?
curl http://localhost:3000/api/inngest
# → 404? Your serve handler isn't registered at this path
# Does it list your functions?
curl http://localhost:3000/api/inngest | jq '.functionsFound'
# → 0? Your functions aren't added to the serve() handler's functions array
# Does it list the right functions?
curl http://localhost:3000/api/inngest | jq '.functions[].id'
# → Missing one? Check the import in your serve route
Part 10: The MCP Integration
The Dev Server now supports Model Context Protocol (MCP) — allowing AI coding assistants like Claude Code or Cursor to connect directly to your local Dev Server.
The MCP server provides comprehensive access to your development environment with 8 powerful tools: event management (send events and discover registered functions), real-time monitoring (track function execution and debug failures with detailed traces), direct function invocation, documentation access, and integration testing (poll multiple runs to verify complex workflows).
To connect your AI assistant:
// Add to your AI assistant's MCP configuration
{
"mcpServers": {
"inngest-dev": {
"command": "curl",
"args": [
"-X",
"POST",
"http://127.0.0.1:8288/mcp",
"-H",
"Content-Type: application/json",
"-d",
"@-"
]
}
}
}
With this connected, your AI assistant can:
- Trigger functions by name without you copy-pasting payloads
- Read run traces and diagnose failures
- Send test events and poll for results
- Search Inngest documentation inline
This is an optional enhancement — the Dev Server works perfectly without it.
Part 11: A Productive Local Dev Workflow
With everything set up, here's the workflow that makes local development with Inngest fast and low-friction:
1. Start your app
INNGEST_DEV=1 npm run dev
→ App running on http://localhost:3000
2. Start the Dev Server (in a separate terminal)
npx --ignore-scripts=false inngest-cli@latest dev --no-discovery \
-u http://localhost:3000/api/inngest
→ Dev Server running on http://localhost:8288
3. Open the Dev Server in your browser
http://localhost:8288
4. Write your function in your IDE
→ Dev Server polls and picks up changes automatically
5. Test with Invoke (fastest)
Functions tab → select function → Invoke → paste payload → run
6. Watch the run timeline
Runs tab → click the run → inspect step outputs
7. Fix a bug
Edit your code → save → the hot reload takes effect
Dev Server picks up the new code on next poll (within ~2s)
8. Replay the failed run
Runs tab → click the failed run → Replay
→ New run with same payload, new code
9. Repeat until the run timeline shows all green
The Dev Server hot-reloads function definitions as your code changes — you don't need to restart it between edits. The polling interval is a few seconds, so your changes are picked up almost immediately.
Common Misconceptions
❌ Misconception: You need to restart the Dev Server when you change your functions
Reality: The Dev Server polls your /api/inngest endpoint continuously for changes. When you save a file, your framework hot-reloads (Next.js, tsx --watch, etc.), and the Dev Server picks up the updated function list on its next poll — usually within 2–3 seconds. No restart needed.
Exception: If you add a new function file, make sure it's imported and listed in your serve() handler, or the new function won't appear even after hot reload.
❌ Misconception: The Dev Server is a simplified version of Inngest Cloud
Reality: As Inngest's documentation describes, it is a "fully-featured and open-source local version of the Inngest Platform." The same binary powers both. The feature set, execution model, and observability are identical — only the scale and the signing key validation differ.
❌ Misconception: Replay re-uses step results from the original run
Reality: Replay creates a brand new run with the same original event payload. There's no memoisation between runs — all steps execute fresh. This is intentional: you want your fixed code to re-run all the steps, not skip to where it failed.
❌ Misconception: You need INNGEST_EVENT_KEY set locally
Reality: The Dev Server doesn't validate event keys. You can use any string — or even omit the env var entirely — when developing locally. Event keys are only validated by Inngest Cloud in production.
Troubleshooting Common Issues
Problem: No functions appear in the Dev Server
Step-by-step diagnosis:
# Step 1: Is your app running?
curl http://localhost:3000
# → connection refused? Start your app first
# Step 2: Does the Inngest endpoint exist?
curl http://localhost:3000/api/inngest
# → 404? Check your serve handler is registered at this path
# Step 3: Does it list your functions?
curl http://localhost:3000/api/inngest | grep functionsFound
# → "functionsFound": 0? Check your functions are in the serve() array
# Step 4: Is the Dev Server pointing at the right URL?
# Check the Apps tab in the Dev Server UI
# The URL should match your app's actual address
Problem: Function runs twice for every event
Cause: Auto-discovery found your app AND you passed -u manually — the Dev Server connected twice.
Fix:
# Add --no-discovery to prevent auto-discovery when using -u
npx --ignore-scripts=false inngest-cli@latest dev \
--no-discovery \
-u http://localhost:3000/api/inngest
Problem: Replay didn't use my fixed code — it still failed the same way
Most likely cause: Your code change didn't actually take effect before the replay. Check that:
- Your file was saved
- Your hot-reload (Next.js, tsx --watch) actually restarted with the new code
- The Dev Server polled and picked up the new function definition (check the Apps tab — the "Last synced" timestamp should be recent)
A quick way to verify: check the SDK debug endpoint for the updated function after your save:
curl http://localhost:3000/api/inngest | jq '.functions'
Check Your Understanding
Quick Quiz
1. You fire an event via inngest.send() in your app, but no run appears in the Runs tab. What are the three most likely causes and how do you diagnose each?
Show Answer
Cause 1: The event never reached the Dev Server.
Check the Events tab. If the event isn't there, inngest.send() isn't routing to the Dev Server. Verify INNGEST_DEV=1 is set and the Dev Server is actually running.
Cause 2: The event arrived but no function has a matching trigger.
Check the Events tab — if the event is there but shows "0 functions triggered," your event name doesn't match any function's trigger expression. Check for typos: "user/account.created" vs "user/account-created", for example.
Cause 3: The function isn't registered in the serve handler.
Check the Functions tab — is your function listed? If not, it's not in the functions array of serve(). Add it and save.
2. What's the difference between the Invoke button and the Test Event button?
Show Answer
Invoke calls a specific function directly — it bypasses the event system. Only that one function runs. Event-level deduplication is bypassed. The event doesn't appear in the Events tab.
Test Event sends an actual event through the full event pipeline — it appears in the Events tab and triggers every function that has a matching trigger. If three functions listen to user/account.created, all three run. This mirrors what happens in production when inngest.send() is called.
Use Invoke for isolated function testing. Use Test Event for testing the full fan-out flow.
3. You fixed a bug in step 2 of a 4-step function. You replay the failed run. Which steps execute their callback code?
Show Answer
All four steps — the replay creates a brand new run with empty step state. There's no memoisation carried over from the original run. Step 1 runs fresh, step 2 runs with your fix, steps 3 and 4 run for the first time.
This is the correct behaviour: you want your fixed code to execute all the way through, not just from the point of failure. If you wanted to skip step 1, you'd need to make step 1 idempotent (which you should anyway) and just run the whole thing again.
Summary: Key Takeaways
- Five tabs: Apps (connection status), Functions (list + Invoke), Runs (execution history), Events (event log), and the Run detail view (step timeline + data inspection).
- Four testing methods: Invoke (isolated), Test Event (full pipeline),
inngest.send()from app code (production-realistic), and direct HTTP to/e/key(automation/CI). - Reading run traces: Each step shows all attempts, durations, error messages, and return values — follow the data through the chain to find where things go wrong.
- Replay vs Invoke: Replay uses the original event payload with a fresh run. Use it after fixing bugs. Invoke lets you provide a new payload.
- Auto-discovery finds your app automatically but can cause duplicate runs if combined with
-u. Use--no-discoverywhen specifying URLs explicitly. inngest.jsonis the config file for team-shared settings — commit it to your repo.- The SDK debug endpoint (
GET /api/inngest) is your diagnostic tool for "why isn't my function appearing?" - No account, no API key required for local development. The Dev Server runs entirely on your machine.
- Hot reloads automatically — save your code, the Dev Server picks up changes within seconds.
What's Next?
You're now fluent with the local development environment. You can test, debug, replay, and iterate fast.
In Article 12: Deploying Inngest to Production (coming soon), we take everything you've built locally and connect it to Inngest Cloud. You'll learn about signing keys, event keys, syncing your app, environment separation, and verifying your deployment is working correctly.
Version Information
Tested with:
inngest-cli:latest(runnpx inngest-cli@latest --versionto check)inngestSDK:^4.1.x- Node.js: v18.x, v20.x, v22.x
Dev Server port: Default 8288. Override with --port <n>.
Function polling interval: ~2 seconds (not configurable via CLI flags).
Further reading:
- Local Development — Inngest Documentation — official guide with all CLI flags and Docker examples
- Introducing the Inngest Dev Server — Inngest Blog — background on the Dev Server's design and capabilities
- Dev Server MCP — Inngest Documentation — connecting AI assistants to the Dev Server
- Self-hosting — Inngest Documentation — the same binary for production self-hosting
- Inngest Open Source (GitHub) — source code for the Dev Server