Inngest

Serverless event-driven systems, background jobs, and scheduled jobs for Ty...

README




Serverless event-driven queues, background jobs, and scheduled jobs for Typescript.

    Works with any framework and platform.

Read the documentation and get started in minutes.



On _any_ serverless platform (Next.js, Deno Deploy, RedwoodJS, AWS Lambda, and anything else) and with no extra infrastructure:

- ⚡ Write background jobs- 🕐 Create scheduled & cron jobs- ♻️ Build serverless queues- 🪜 Write complex step functions- 🚘 Build serverless event-driven systems
- 🪝 Reliably respond to webhooks, with retries & payloads stored for history

👋 _Have a question or feature request? Join our Discord!_



Getting started ·Features ·Contributing ·Documentation




Getting started




Install Inngest:

  1. ```bash
  2. npm install inngest  # or yarn add inngest
  3. ```

Writing functions


Write serverless functions and background jobs right in your own code:

  1. ```ts
  2. import { Inngest } from "inngest";

  3. const inngest = new Inngest({ name: "My App" });

  4. // This function will be invoked by Inngest via HTTP any time
  5. // the "app/user.signup" event is sent to to Inngest
  6. export default inngest.createFunction(
  7.   { name: "User onboarding communication" },
  8.   { event: "app/user.signup" },
  9.   async ({ event, step }) => {
  10.     await step.run("Send welcome email", async () => {
  11.       await sendEmail({
  12.         email: event.data.email,
  13.         template: "welcome",
  14.       });
  15.     });
  16.   }
  17. );
  18. ```

- Functions are triggered by events which can be sent via this SDK, webhooks, integrations, or with a simple HTTP request.
- When a matching event is received, Inngest invokes the function automatically, with built-in retries.

Serving your functions


Inngest invokes functions via HTTP, so you need to _serve_ them using an adapter for the framework of your choice. See all frameworks here in our docs. Here is an example using the Next.js serve handler:

  1. ```ts
  2. // /pages/api/inngest.ts
  3. import { Inngest } from "inngest";
  4. // See the "inngest/next" adapter imported here:
  5. import { serve } from "inngest/next";
  6. import myFunction from "../userOnboardingCOmmunication"; // see above function

  7. // You can create this in a single file and import where it's needed
  8. const inngest = new Inngest({ name: "My App" });

  9. // Securely serve your Inngest functions for remote invocation:
  10. export default serve(inngest, [myFunction]);
  11. ```

Sending events to trigger functions


  1. ```ts
  2. // Send events
  3. import { Inngest } from "inngest";
  4. const inngest = new Inngest({ name: "My App" });

  5. // This will run the function above automatically, in the background
  6. inngest.send("app/user.signup", {
  7.   data: { email: "text@example.com", user_id: "12345" },
  8. });
  9. ```

- Events can trigger one or more functions automatically, enabling you to fan-out work.
- Inngest stores a history of all events for observability, testing, and replay.



Features


- Fully serverless: Run background jobs, scheduled functions, and build event-driven systems without any servers, state, or setup
- Deploy anywhere: Keep deploying to your existing platform: Vercel, Netlify, Cloudflare, Deno, Digital Ocean, etc.
- Use your existing code: Write functions within your current project and repo
- Fully typed: Event schemas, versioning, and governance out of the box
- Observable: A full UI for managing and inspecting your functions



Contributing


Clone the repository, then:

  1. ```sh
  2. yarn dev # install dependencies, build/lint/test
  3. ```

We use Volta to manage Node/Yarn versions.

When making a pull request, make sure to commit the changed etc/inngest.api.md file; this is a generated types/docs file that will highlight changes to the exposed API.


Locally linking (npm|yarn link)


In order to provide sensible namespaced imports such as "inngest/next", the package actually builds to _and deploys from_ dist/.

To replicate this locally to test changes with other local repos, you can link the project like so (replace npm for yarn if desired):

  1. ```sh
  2. # in this repo
  3. yarn build
  4. yarn prelink
  5. cd dist/
  6. yarn link

  7. # in another repo
  8. yarn link inngest
  9. ```

Alternatively, you can also package the library and ship it with an application. This is a nice way to generate and ship snapshot/test versions of the library to test in production environments without requiring releasing to npm.

  1. ```sh
  2. # in this repo
  3. yarn local:pack
  4. cp inngest.tgz ../some-other-repo-root

  5. # in another repo
  6. yarn add ./inngest.tgz
  7. ```

Some platforms require manually installing the package again at build time to properly link dependencies, so you may have to change your yarn build script to be prefixed with this install, e.g.:

  1. ```sh
  2. yarn add ./inngest.tgz && framework dev
  3. ```

Releasing


To release to production, we use Changesets. This means that releasing and changelog generation is all managed through PRs, where a bot will guide you through the process of announcing changes in PRs and releasing them once merged tomain.

Snapshot versions


If a local inngest.tgz isn't ideal, we can release a tagged version to npm. For now, this is relatively manual. For this, please ensure you are in an open PR branch for observability.

Decide on the "tag" you will be publishing to, which will dictate how the user installs the snapshot, e.g. if your tag is beta, the user will install using inngest@beta.

You can see the currently available tags on the [inngest npm page](https://www.npmjs.com/package/inngest?activeTab=versions).

NEVER use the latest tag, and NEVER run npm publish without specifying --tag.


If the current active version is v1.1.1, this is a minor release, and our tag is foo, we'd do:

  1. ```sh
  2. yarn version v1.2.0-foo.1
  3. yarn build
  4. yarn prelink
  5. cd dist/
  6. npm publish --access public --tag foo
  7. ```

You can iterate the final number for each extra snapshot you need to do on a branch.