A background job can finish several operations before a crash stops it.
Restarting the whole job can repeat work that already succeeded. OpenWorkflow
saves progress between steps so your code can resume after a crash or deploy.You write workflows in TypeScript or JavaScript and wrap operations in steps.
Workers execute them and save the results in PostgreSQL or SQLite. Workflows can
retry failed steps, pause on a timer, or wait for a signal before continuing.
Your application and workers connect directly to your database, so you can run
OpenWorkflow on your own infrastructure.Use it for background jobs, multi-step integrations, data pipelines, and AI
workflows that need to keep their progress. The Quick Start
walks through running a workflow locally, and the overview
explains how workflows, steps, and workers fit together.
OpenWorkflow is developed on
GitHub under the Apache-2.0
license.
The repository includes the workflow engine, CLI, dashboard, documentation, and
examples. Bugs, feature proposals, and code changes are discussed there.Contributions can be code, documentation fixes, bug reports, or feedback from
using OpenWorkflow. Read the contribution
guide
before starting a change, and check the roadmap for planned
work. See Contact for where to ask questions or report a problem.
{"docsConfig":{"theme":"linden","$schema":"https://mintlify.com/docs.json","name":"OpenWorkflow","description":"Open-source durable workflow engine for TypeScript, powered by PostgreSQL or SQLite.","colors":{"primary":"#000000"},"favicon":"https://mintcdn.com/openworkflow/g0_AfecrUfrQ6T2J/favicon.ico?fit=max\u0026auto=format\u0026n=g0_AfecrUfrQ6T2J\u0026q=85\u0026s=b8aa825e4c0666d854fcf0ea457a4c8e","footer":{"socials":{"github":"https://github.com/openworkflowdev/openworkflow","discord":"https://discord.openworkflow.dev"},"links":[{"items":[{"label":"About","href":"/about"},{"label":"Contact","href":"/contact"},{"label":"npm","href":"https://www.npmjs.com/package/openworkflow"}]}]},"seo":{"organization":{"sameAs":["https://github.com/openworkflowdev"]}},"integrations":{"ga4":{"measurementId":"G-MJ06221ME3"},"posthog":{"apiKey":"phc_C1Cm1NAKHDFA3eKLVqcYzR5wUk8WhSbMMXltk5Qj1Ye"}},"markdown":{"instructions":["### When to use OpenWorkflow","","Use OpenWorkflow in TypeScript or JavaScript apps for:","","- Background jobs that need retries and must resume after a crash or deploy.","- Multi-step integrations and data pipelines that need to save progress between operations.","- AI workflows with multiple model or tool calls that need durable checkpoints.","- Workflows that wait for a human approval, a webhook, or a timer before continuing.","","OpenWorkflow runs on Node.js 22.22+ or Bun, with PostgreSQL or SQLite storing workflow state. Your app enqueues runs, and a worker executes them.","","### How to use OpenWorkflow","","Read and follow https://openworkflow.dev/skills/setup.md to set up OpenWorkflow.","","Define workflows with `defineWorkflow`, wrap operations in `step.run`, and enqueue runs with `ow.runWorkflow(workflow.spec, input)`. Start a worker with `npx @openworkflow/cli worker start` to execute them. See [Workflows](https://openworkflow.dev/docs/workflows.md), [Steps](https://openworkflow.dev/docs/steps.md), and [Signals](https://openworkflow.dev/docs/signals.md) for the APIs."]},"styling":{"latex":false},"background":{"color":{"light":"#f7f7f7","dark":"#0b0f0f"}},"navigation":{"global":{"anchors":[{"anchor":"Star on GitHub","icon":"star","href":"https://github.com/openworkflowdev/openworkflow"},{"anchor":"Join Discord 👾","icon":"discord","href":"https://discord.openworkflow.dev"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"openworkflow","hasAudioNarration":false,"actualSubdomain":"openworkflow","customDomains":["openworkflow.dev"],"gitSource":{"type":"github","owner":"openworkflowdev","repo":"openworkflow","deployBranch":"docs","contentDirectory":"apps/docs","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6acd60629df5b0393f7db990","collectionId":"b56033c1-a77e-4372-9449-2f8956392ab2","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6acd60629df5b0393f7db990"},"feedback":{"thumbs":true,"edits":true,"issues":false},"entitlements":{},"buildId":"6acd60629df5b0393f7db990","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"Guides","count":11},{"language":"default","tag":"Resources","count":8},{"language":"default","tag":"Comparisons","count":5},{"language":"default","tag":"Integrations","count":4},{"language":"default","tag":"Core Concepts","count":4},{"language":"default","tag":"Reference","count":3},{"language":"default","tag":"Backends","count":3},{"language":"default","tag":"Project","count":2},{"language":"default","tag":"Get Started","count":2},{"language":"default","tag":"Agent Skills","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"#pagination,.eyebrow,button[aria-label=\"More actions\"]{display:none}"}],"page":{"pagePath":"about","slug":"/about","pageMetadata":{"title":"About OpenWorkflow","sidebarTitle":"About","description":"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project","href":"/about"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,p:`p`,..._provideComponents(),...props.components},{Heading}=_components;if(!Heading)_missingMdxReference(`Heading`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`why-openworkflow-exists`,children:`Why OpenWorkflow exists`}),`\n`,_jsx(_components.p,{children:`A background job can finish several operations before a crash stops it.\nRestarting the whole job can repeat work that already succeeded. OpenWorkflow\nsaves progress between steps so your code can resume after a crash or deploy.`}),`\n`,_jsx(_components.p,{children:`You write workflows in TypeScript or JavaScript and wrap operations in steps.\nWorkers execute them and save the results in PostgreSQL or SQLite. Workflows can\nretry failed steps, pause on a timer, or wait for a signal before continuing.\nYour application and workers connect directly to your database, so you can run\nOpenWorkflow on your own infrastructure.`}),`\n`,_jsxs(_components.p,{children:[`Use it for background jobs, multi-step integrations, data pipelines, and AI\nworkflows that need to keep their progress. The `,_jsx(_components.a,{href:`/docs/quickstart`,children:`Quick Start`}),`\nwalks through running a workflow locally, and the `,_jsx(_components.a,{href:`/docs/overview`,children:`overview`}),`\nexplains how workflows, steps, and workers fit together.`]}),`\n`,_jsx(Heading,{level:`2`,id:`an-open-source-project`,children:`An open-source project`}),`\n`,_jsxs(_components.p,{children:[`OpenWorkflow is developed on\n`,_jsx(_components.a,{href:`https://github.com/openworkflowdev/openworkflow`,children:`GitHub`}),` under the `,_jsx(_components.a,{href:`https://github.com/openworkflowdev/openworkflow/blob/main/LICENSE.md`,children:`Apache-2.0\nlicense`}),`.\nThe repository includes the workflow engine, CLI, dashboard, documentation, and\nexamples. Bugs, feature proposals, and code changes are discussed there.`]}),`\n`,_jsxs(_components.p,{children:[`Contributions can be code, documentation fixes, bug reports, or feedback from\nusing OpenWorkflow. Read the `,_jsx(_components.a,{href:`https://github.com/openworkflowdev/openworkflow/blob/main/CONTRIBUTING.md`,children:`contribution\nguide`}),`\nbefore starting a change, and check the `,_jsx(_components.a,{href:`/docs/roadmap`,children:`roadmap`}),` for planned\nwork. See `,_jsx(_components.a,{href:`/contact`,children:`Contact`}),` for where to ask questions or report a problem.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"About OpenWorkflow","sidebarTitle":"About","description":"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project","href":"/about"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Why OpenWorkflow exists","slug":"why-openworkflow-exists","depth":2,"children":[]},{"title":"An open-source project","slug":"an-open-source-project","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"openworkflow","siteName":"OpenWorkflow","title":"About OpenWorkflow - OpenWorkflow","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-17T18:48:20.504Z","originalFileLocation":"about.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\">\u003cmeta data-mint-head name=\"application-name\" content=\"OpenWorkflow\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"About OpenWorkflow - OpenWorkflow\">\u003cmeta data-mint-head property=\"og:description\" content=\"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"OpenWorkflow\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://openworkflow.dev/about\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://openworkflow.mintlify.app/_mintlify/api/og/v2?division=Project\u0026amp;title=About+OpenWorkflow\u0026amp;description=Why+OpenWorkflow+exists%2C+how+it+runs+durable+workflows%2C+and+how+to+contribute+to+the+open-source+project\u0026amp;theme=5c3c6dcef005b54880073f36\u0026amp;signature=65bb144222948ac4acd541fdc5c5b230f76d8dcf479905a861039cc861293ce5\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"About OpenWorkflow - OpenWorkflow\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://openworkflow.mintlify.app/_mintlify/api/og/v2?division=Project\u0026amp;title=About+OpenWorkflow\u0026amp;description=Why+OpenWorkflow+exists%2C+how+it+runs+durable+workflows%2C+and+how+to+contribute+to+the+open-source+project\u0026amp;theme=5c3c6dcef005b54880073f36\u0026amp;signature=65bb144222948ac4acd541fdc5c5b230f76d8dcf479905a861039cc861293ce5\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/openworkflow/VrvE46zb7xLQiJ7m/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"OpenWorkflow\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#000000\">\u003clink data-mint-head rel=\"canonical\" href=\"https://openworkflow.dev/about\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/about.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://openworkflow.dev/#organization\",\"name\":\"OpenWorkflow\",\"url\":\"https://openworkflow.dev\",\"sameAs\":[\"https://github.com/openworkflowdev\"]},{\"@type\":\"WebSite\",\"@id\":\"https://openworkflow.dev#website\",\"name\":\"OpenWorkflow\",\"url\":\"https://openworkflow.dev\",\"publisher\":{\"@id\":\"https://openworkflow.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://openworkflow.dev/about#webpage\",\"url\":\"https://openworkflow.dev/about\",\"name\":\"About OpenWorkflow\",\"description\":\"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\",\"dateModified\":\"2026-09-17T18:48:20.504Z\",\"isPartOf\":{\"@id\":\"https://openworkflow.dev#website\"},\"breadcrumb\":{\"@id\":\"https://openworkflow.dev/about#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://openworkflow.dev/about#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"OpenWorkflow\",\"item\":\"https://openworkflow.dev\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"About OpenWorkflow\",\"item\":\"https://openworkflow.dev/about\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://openworkflow.dev/about#article\",\"headline\":\"About OpenWorkflow\",\"name\":\"About OpenWorkflow\",\"description\":\"Why OpenWorkflow exists, how it runs durable workflows, and how to contribute to the open-source project\",\"url\":\"https://openworkflow.dev/about\",\"mainEntityOfPage\":{\"@id\":\"https://openworkflow.dev/about#webpage\"},\"dateModified\":\"2026-09-17T18:48:20.504Z\",\"publisher\":{\"@id\":\"https://openworkflow.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://openworkflow.dev#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"OpenWorkflow\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"OpenWorkflow","nav":{"global":{"anchors":[{"anchor":"Star on GitHub","icon":"star","href":"https://github.com/openworkflowdev/openworkflow"},{"anchor":"Join Discord 👾","icon":"discord","href":"https://discord.openworkflow.dev"}]},"groups":[{"group":"Get Started","pages":[{"title":"OpenWorkflow","sidebarTitle":"Introduction","mode":"wide","href":"/index"},{"title":"Quick Start","href":"/docs/quickstart"}]},{"group":"Core Concepts","pages":[{"title":"Overview","href":"/docs/overview"},{"title":"Workflows","href":"/docs/workflows"},{"title":"Steps","href":"/docs/steps"},{"title":"Workers","href":"/docs/workers"}]},{"group":"Guides","pages":[{"title":"Sleeping","href":"/docs/sleeping"},{"title":"Recurring schedules","href":"/docs/schedules"},{"title":"Parallel Steps","href":"/docs/parallel-steps"},{"title":"Dynamic Steps","href":"/docs/dynamic-steps"},{"title":"Child Workflows","href":"/docs/child-workflows"},{"title":"Signals","href":"/docs/signals"},{"title":"Retries","href":"/docs/retries"},{"title":"Type Safety","href":"/docs/type-safety"},{"title":"Versioning","href":"/docs/versioning"},{"title":"Canceling Workflows","href":"/docs/canceling"},{"title":"Production","href":"/docs/production"}]},{"group":"Backends","pages":[{"title":"PostgreSQL Backend","href":"/docs/postgres"},{"title":"SQLite Backend","href":"/docs/sqlite"},{"title":"Namespaces","href":"/docs/namespaces"}]},{"group":"Reference","pages":[{"title":"Configuration","href":"/docs/configuration"},{"title":"CLI Reference","href":"/docs/cli"},{"title":"Dashboard","href":"/docs/dashboard"}]},{"group":"Integrations","pages":[{"title":"Standard Schema","href":"/docs/standard-schema"},{"title":"OpenTelemetry","href":"/docs/opentelemetry"},{"title":"Sentry","href":"/docs/sentry"},{"title":"Prometheus Metrics","href":"/docs/prometheus"}]},{"group":"Resources","pages":[{"title":"Roadmap","href":"/docs/roadmap"},{"title":"Building with LLMs","href":"/docs/llms"},{"group":"Agent Skills","expanded":false,"pages":[{"title":"Setup","href":"/skills/setup"}]},{"group":"Comparisons","expanded":false,"pages":[{"title":"Temporal alternative for TypeScript workflows","sidebarTitle":"OpenWorkflow vs Temporal","href":"/docs/openworkflow-vs-temporal"},{"title":"BullMQ alternative for multi-step background jobs","sidebarTitle":"OpenWorkflow vs BullMQ","href":"/docs/openworkflow-vs-bullmq"},{"title":"Inngest alternative for self-hosted workflows","sidebarTitle":"OpenWorkflow vs Inngest","href":"/docs/openworkflow-vs-inngest"},{"title":"Trigger.dev alternative for self-hosted tasks","sidebarTitle":"OpenWorkflow vs Trigger.dev","href":"/docs/openworkflow-vs-trigger-dev"},{"title":"Vercel Workflow alternative for Node.js and Bun","sidebarTitle":"OpenWorkflow vs Vercel Workflow","description":"Compare OpenWorkflow and the Vercel Workflow SDK for build requirements, runtime restrictions, and self-hosting with PostgreSQL or SQLite.","href":"/docs/openworkflow-vs-vercel-workflow"}]}]},{"group":"Project","hidden":true,"searchable":true,"pages":[{"title":"About OpenWorkflow","sidebarTitle":"About","href":"/about"},{"title":"Contact OpenWorkflow","sidebarTitle":"Contact","description":"Ask questions about OpenWorkflow on Discord, or use GitHub to report bugs, suggest features, and contribute","href":"/contact"}]}]},"basePath":"","title":"About OpenWorkflow - OpenWorkflow","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":[],"chunks":[]}