Skip to content

Repository files navigation

Durable Task SDK for JavaScript/TypeScript

Build statusLicense: MIT

This repo contains a JavaScript/TypeScript SDK for use with the Azure Durable Task Scheduler. With this SDK, you can define, schedule, and manage durable orchestrations using ordinary TypeScript/JavaScript code.

Note that the core @microsoft/durabletask-js package does not provide the Azure Durable Functions programming model, decorators, or worker-indexing metadata — it exposes low-level TaskHubSidecarService gRPC/protobuf helpers that host integrations can reuse (Node.js 22+). For the Azure Durable Functions programming model on the gRPC core, this repository also contains the durable-functions provider package under packages/azure-functions-durable. The classic v3 (extension-HTTP) predecessor lives at azure-functions-durable-js.

Low-level host integration APIs

Host integrations that already own trigger metadata and transport encoding can depend on the @microsoft/durabletask-js package directly. TaskHubGrpcWorker registers orchestrators, activities, and entities, and can process raw TaskHubSidecarService protobuf payloads without starting the long-running gRPC worker loop:

constworker=newTaskHubGrpcWorker();worker.addOrchestrator(myOrchestrator);worker.addActivity(myActivity);worker.addEntity(myEntity);constorchestrationResponseBytes=awaitworker.processOrchestratorRequest(orchestrationRequestBytes);constentityResponseBytes=awaitworker.processEntityBatchRequest(entityBatchRequestBytes);

TaskHubGrpcClient already exposes orchestration start/query/event/terminate/suspend/resume/purge APIs and entity signal/read/query/clean APIs through its existing hostAddress and metadataGenerator options. Host integrations that need task-hub routing metadata should provide it through metadataGenerator, keeping host-specific metadata policy outside the core client. Azure-managed scheduler connection strings remain in @microsoft/durabletask-js-azuremanaged.

npm packages

The following npm packages are available for download.

NameLatest versionDescription
Core SDKnpm versionCore Durable Task SDK for JavaScript/TypeScript.
AzureManaged SDKnpm versionAzure-managed Durable Task Scheduler support for the Durable Task JavaScript SDK.

Prerequisites

Usage with the Durable Task Scheduler

This SDK can be used with the Durable Task Scheduler, a managed backend for running durable orchestrations in Azure.

To get started, install the npm packages:

npm install @microsoft/durabletask-js @microsoft/durabletask-js-azuremanaged

You can then use the following code to define a simple "Hello, cities" durable orchestration.

import{ActivityContext,OrchestrationContext,TOrchestrator}from"@microsoft/durabletask-js";import{createAzureManagedClient,createAzureManagedWorkerBuilder}from"@microsoft/durabletask-js-azuremanaged";// Define an activity functionconstsayHello=async(_: ActivityContext,name: string): Promise<string>=>{return`Hello, ${name}!`;};// Define an orchestrator functionconsthelloCities: TOrchestrator=asyncfunction*(ctx: OrchestrationContext): any{constresult1=yieldctx.callActivity(sayHello,"Tokyo");constresult2=yieldctx.callActivity(sayHello,"London");constresult3=yieldctx.callActivity(sayHello,"Seattle");return[result1,result2,result3];};// Create client and worker using a connection stringconstconnectionString=process.env.DURABLE_TASK_SCHEDULER_CONNECTION_STRING!;constclient=createAzureManagedClient(connectionString);constworker=createAzureManagedWorkerBuilder(connectionString).addOrchestrator(helloCities).addActivity(sayHello).build();// Start the worker and schedule an orchestrationawaitworker.start();constid=awaitclient.scheduleNewOrchestration(helloCities);conststate=awaitclient.waitForOrchestrationCompletion(id,true,60);console.log(`Result: ${state?.serializedOutput}`);

You can find more samples in the examples/azure-managed directory.

Reusing orchestration instance IDs

Set the top-level dedupeStatuses start option when an instance ID may be reused. The list contains the existing runtime statuses that must continue to produce an OrchestrationAlreadyExistsError; instances in every other supported runtime status are atomically replaced:

import{OrchestrationStatus}from"@microsoft/durabletask-js";awaitclient.scheduleNewOrchestration(helloCities,undefined,{instanceId: "daily-greeting",dedupeStatuses: [OrchestrationStatus.RUNNING,OrchestrationStatus.PENDING],});

For TaskHubGrpcClient, omitting dedupeStatuses preserves the backend's default duplicate-ID behavior; passing [] makes every supported runtime status replaceable. The in-memory TestOrchestrationClient mirrors the .NET shim, where omission also makes all statuses reusable. ValidDedupeStatuses exports the seven supported statuses. The transient CONTINUED_AS_NEW status is not replaceable. A list containing TERMINATED must also contain RUNNING, PENDING, and SUSPENDED, because replacing a running instance first terminates it. The production client forwards this validation to the backend and maps its INVALID_ARGUMENT response to TypeError; the in-memory client validates it directly. The current shared protocol does not define a no-op/IGNORE action: a matching dedupe status is an error, while a non-matching status is replaced.

Supported patterns

The following orchestration patterns are supported.

Function chaining

The getting-started example above demonstrates function chaining, where an orchestration calls a sequence of activities one after another. You can find the full sample at examples/hello-world/activity-sequence.ts.

Fan-out/fan-in

An orchestration can fan-out a dynamic number of function calls in parallel and then fan-in the results:

import{whenAll}from"@microsoft/durabletask-js";constorchestrator: TOrchestrator=asyncfunction*(ctx: OrchestrationContext): any{constworkItems=yieldctx.callActivity(getWorkItems);consttasks=[];for(constitemofworkItems){tasks.push(ctx.callActivity(processWorkItem,item));}constresults: number[]=yieldwhenAll(tasks);returnresults.reduce((sum,val)=>sum+val,0);};

You can find the full sample at examples/hello-world/fanout-fanin.ts.

Human interaction and durable timers

An orchestration can wait for external events, such as a human approval, with optional timeout handling:

import{whenAny}from"@microsoft/durabletask-js";constpurchaseOrderWorkflow: TOrchestrator=asyncfunction*(ctx: OrchestrationContext,order: Order): any{// Orders under $1000 are auto-approvedif(order.cost<1000){return"Auto-approved";}// Orders of $1000 or more require manager approvalyieldctx.callActivity(sendApprovalRequest,order);// Approvals must be received within 24 hours or they will be canceledconstapprovalEvent=ctx.waitForExternalEvent("approval_received");consttimeoutEvent=ctx.createTimer(24*60*60);constwinner=yieldwhenAny([approvalEvent,timeoutEvent]);if(winner==timeoutEvent){return"Cancelled";}yieldctx.callActivity(placeOrder,order);constapprovalDetails=approvalEvent.getResult();return`Approved by ${approvalDetails.approver}`;};

You can find the full sample at examples/hello-world/human_interaction.ts.

Durable entities

Durable entities provide a way to manage small pieces of state with a simple object-oriented programming model:

import{TaskEntity}from"@microsoft/durabletask-js";interfaceCounterState{value: number;}classCounterEntityextendsTaskEntity<CounterState>{add(amount: number): number{this.state.value+=amount;returnthis.state.value;}get(): number{returnthis.state.value;}reset(): void{this.state.value=0;}protectedinitializeState(): CounterState{return{value: 0};}}// Register with the workerworker.addNamedEntity("Counter",()=>newCounterEntity());

You can find the full entity samples at examples/entity-counter and examples/entity-orchestration.

Obtaining the Protobuf definitions

This project utilizes protobuf definitions from durabletask-protobuf. To download the latest proto files, run:

npm run download-proto

This will download the proto files to internal/durabletask-protobuf/protos/. Once the proto files are available, the corresponding TypeScript source code can be regenerated using:

npm run generate-grpc

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

About

A Durable Task JavaScript SDK compatible with Azure Durable Task Scheduler

Topics

Resources

Code of conduct

Security policy

Stars

13 stars

Watchers

3 watching

Forks

Releases

Used by

Contributors

Languages