Announcing our new Vercel integration
Join our Discord
Sign up for free

Writing functions

Follow along to learn how to:

  • Write a background function triggered by an event
  • Write a scheduled function

Writing functions is the same no matter what platform you deploy to — so this example can be used for any TypeScript or JavaScript project (such as NextJS, Netlify, or Lambda).

Install the SDK

Firstly, you need to install the SDK via npm or yarn:

bash
npm install inngest # or yarn add inngest

Writing a background function

Copy the following code into a new file in your project, for example within ./inngest/function.ts

typescript
import { createFunction } from "inngest";
// This function runs the code and will be called in the background.
const job = async ({ event }) => {
return "hello!"; // You can write whatever you want here.
}
export const demoFunction = createFunction<DemoEvent>(
"Demo function", // The name of your function, used for observability.
"demo/demo.event", // The event that triggers this function.
job, // The function code, defined above.
)

This defines a new background job which runs any code that you pass it. This function is automatically triggered in the background whenever the demo/test.event event is received. You can test this function using standard tooling such as Jest or Mocha by exporting the job code and running standard unit tests.

Writing a scheduled function

The following code defines a scheduled function, which runs automatically using the specified cron schedule:

typescript
import { createScheduledFunction } from "inngest";
// This code will be called by the scheduled function.
const job = async () => {
return "hello!"; // You can write whatever you want here.
}
export createScheduledFunction(
"Demo function", // The name of your function, used for observability.
"0 * * * *", // The cron syntax for the function
job, // The function code, defined above.
)

This is very similar to defining an event-driven function, except it uses the createScheduledFunction call and a cron schedule to run your function at the specified interval. This code can be deployed to any platform and will run automatically, without any HTTP calls.

Writing a multi-step function

The following code defines a multi-step function, which you can use to coordinate between events, work with delays, and safely handle multiple asynchronous steps.

typescript
export default createStepFunction(
"Activation email",
"app/user.created",
({ event, tools }) => {
// Send the user a welcome email
tools.run("Send welcome email", () =>
sendEmail({ email: event.user.email, template: "welcome" })
);
// Wait for the user to create an order, by waiting and
// matching on another event
const order = tools.waitForEvent("app/order.created", {
match: "data.user.id",
timeout: "24h",
});
if (!order) {
// User didn't create an order within 24 hours; send
// them an activation email
tools.run("Send activation email", async () => {
// Some code here
});
}
}
);

Use a multi-step function to create a logical flow of actions triggered from an initial event. It's just like writing a regular synchronous function, but Inngest will step in to help coordinate between events, wait for long periods, or retry failed steps.

In this example, we send the user a welcome email when they are created, then send an activation email after 24 hours if they haven't created an order in that time. Each call to run() can be retried independently, meaning a failure in one step won't affect any others.

Coordinating between events like this often requires a lot of code and infrastructure to handle retries, timeouts, state, queues, and many edge cases. Inngest handles all of this for you, so you can focus on writing the code that matters in a clean, readable format.

You can learn more about the Inngest SDK's multi-step functions on our Multi-step functions page.

TypeScript

The Inngest SDK lets you strictly type all of your code against your real production data. This powerful feature helps to:

  • Protect you from making breaking changes
  • Encourage discoverability of your events via autocomplete
  • Give you instant feedback as to whether your code will run as intended

To use generated event types, just run the types command on the Inngest CLI. You can do this via npx:

sh
npx inngest-cli types ts [--output my/file.ts]

This will - by default - create a file at ./__generated__/inngest.ts with all of your event types. You can then pass these in to a new Inngest() client.

typescript
import { Inngest } from "inngest";
import { Events } from "./__generated__/inngest";
const inngest = new Inngest<Events>({ name: "My App" });

Or use individual events if using the createFunction helper directly.

typescript
import { createFunction } from "inngest";
import { DemoEvent } from "./__generated__/inngest";
const fn = createFunction<DemoEvent>("Demo function", "demo/demo.event", job);

Finally, sometimes you want to provide type safety before an event has reached your Inngest Cloud account. For this, we can pass extra custom event types to the generated Events type which will be silently overridden when these events appear in Inngest.

typescript
const inngest = new Inngest<
Events<{
"app/user.created": { data: { id: string } };
"app/user.updated": AppUserUpdated;
}>
>({ name: "My App" });

You can learn more about the Inngest SDK's TypeScript support on our Using with TypeScript page.

Serving

You can host your functions right in your existing application on any platform. Inngest will call your functions securely via HTTP request on-demand.

To enable Inngest to access and call your functions, you need to set up the serve() handler to be accessible on it's own route. We recommend setting this up for /api/inngest. The serve() handler requires an INNGEST_SIGNING_KEY to be set as an environment variable, or explicitly passed as an options argument. For example, in a Next.js app, it looks like this:

typescript
// ./pages/api/inngest.ts
// Import the Next.js serve function
import { serve } from "inngest/next";
// Create or import your function(s)
const fn = createFunction<DemoEvent>("Demo function", "demo/demo.event", job);
// Serve them
export default serve("My App", [fn, anotherFn]);

Now that your functions are being served via HTTP, open the route in your browser to view the SDK debug page. It will show you whether your functions are set up correctly, prompt you with what to change if not, and show you any next steps needed along the way!

The SDK's local dashboard showing success

Next up

Triggering functions: next, you’ll run through how you can trigger these functions by sending events.

Deploying: then, you’ll learn how to deploy to your platform of choice so that they’re live.