Skip to main content


Welcome to the Resonate SDK quickstart! This quickstart is designed to give you a rapid introduction to the core concepts and syntax of the Resonate SDK. By the end, you'll have a basic understanding of how to register functions, run them with unique identifiers, and integrate Resonate with a web server.


  • NodeJS
  • npm


Create a project folder.

mkdir resonate-quickstart && cd resonate-quickstart

Install the dev dependencies.

npm init -y && npm install typescript ts-node @types/node --save-dev

Install the app dependencies.

npm install @resonatehq/[email protected] express @types/express


The following application forms a pipeline, where the result of a function is used to execute the next one. The pipeline in this example consists of two steps:

  • The download function retrieves the content from a web page.
  • The summarize function generates a summary of the downloaded content.

Resonate manages the execution of these functions, ensuring that the result of download is passed as input to summarize. In cases of transient or intermittent failures at any step, Resonate will automatically retry the execution, providing reliability to the process.

To see this in action, create a file named index.ts and copy and paste the minimal distributed async/await application below:

import { Resonate, Context } from "@resonatehq/sdk";
import express, { Request, Response } from "express";

async function downloadAndSummarize(ctx: Context, url: string) {
let content = await, url);
let summary = await, content);
return summary;

async function download(ctx: Context, url: string): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.1) {
reject("Download failed due to a network error.");
} else {
resolve("This is the text of the page");
}, 1000);

async function summarize(ctx: Context, text: string): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.1) {
reject("Download failed due to a network error.");
} else {
resolve("This is a summary of the text");
}, 1000);

// 1) Initialize a Resonate application.
const resonate = new Resonate();

// 2) Register a function as a Resonate function.
resonate.options({ timeout: 20000 })

// 3) Start the Resonate application.

const app = express().use(express.json());"/summarize", async (req: Request, res: Response) => {
const url = req.body?.url;
const uid = `summarize-${url}`;
try {
// 4) Run the registered 'downloadAndSummarize' function with the above uid and the following function arguments.
let summary = await"downloadAndSummarize", uid, url);
} catch (e) {
res.status(500).send("An error occurred.");

app.listen(3000, () => {
console.log("Listening on port 3000");

Now we can start the application.

ts-node index.ts

Next, call the endpoint providing a url in the payload of the request.

curl \
-H 'Content-Type: application/json' \
-d '{"url": ""}' \

Notice how subsequent requests with the same URL respond much quicker. This is because when you run a function with Resonate, you give it a unique ID. Resonate remembers this ID and saves the function's progress. If you make another request with the same ID, Resonate quickly continues from where it stopped before, instead of starting over. This is called "replaying" the function.

Next Steps

Fantastic work! You've just created your first distributed async/await application with Resonate. What's next? It depends on your learning style:

  • If you're a code-first kind of learner, eager to see more examples and get your hands dirty, head over to our Typescript Quickstart Repo.
  • If you prefer to dive into concepts and gain a deeper understanding of how Resonate works under the hood, check out our Concepts page.

Happy learning, and happy building!