Ce qui se passe
Un workflow est un graphe orienté acyclique, et la plupart des moteurs — Airflow
en tête — demandent de le dessiner à la main, la logique métier finissant enterrée
dans les nœuds. L'argument du Workflow SDK tient en une observation : un arbre
syntaxique est déjà un DAG. await exprime une dépendance, Promise.all un
parallélisme, une boucle une itération.
Le SDK s'écrit donc dans un seul fichier de code ordinaire, avec deux directives :
export async function processOrderWorkflow(orderId: string) {
"use workflow";
const order = await fetchOrder(orderId);
await chargePayment(order);
return { orderId, status: "completed" };
}
async function chargePayment(order: Order) {
"use step"; // accès Node.js complet ici
const charge = await stripe.charges.create({ /* ... */ });
return { chargeId: charge.id };
}Le compilateur lit les directives et scinde le code en bundles workflow et client/step. Il n'y a pas de fichier de graphe : le graphe, c'est le flux de contrôle.
Le détail qui compte
Les erreurs. Une exception non rattrapée dans une étape déclenche une
nouvelle tentative. FatalError interrompt définitivement,
RetryableError(..., { retryAfter }) pilote le délai, et fn.maxRetries = n
fixe le plafond.
L'attente d'un humain. createWebhook() crée une URL réellement appelable
à l'intérieur d'une exécution : le run se gare là, quelques secondes ou
plusieurs semaines, sans route ni handler à déployer.
const webhook = createWebhook();
await emailManager(expense.managerEmail, webhook.url);
const request = await webhook; // reprend à la réception du POSTC'est du sucre au-dessus d'un primitive plus général, createHook<T>(), qui
remplace à lui seul les signals, queries et updates de Temporal — trois
concepts aux règles distinctes que l'auteur, ancien utilisateur de Temporal, dit
n'avoir jamais réussi à expliquer sans tableau blanc.
Le versionnage. C'est le point dur de l'exécution durable : modifier le code pendant qu'anciennes exécutions tournent casse la relecture d'historique. Temporal répond par une API de patch et un cycle de dépréciation qui finit par émailler le code de drapeaux de version. Ici, chaque exécution est épinglée au déploiement qui l'a démarrée et continue sur la copie exacte du code qu'elle a vue. Le monde Postgres officiel ne route pas encore les versions ainsi — mais une implémentation communautaire, Platformatic sur Kubernetes, le fait déjà.
Ce que ça change
C'est une bibliothèque, pas une plateforme — la forme est empruntée à DBOS, dont le serveur ne demande qu'un Postgres. Aucun orchestrateur à héberger, aucune flotte de workers à exploiter : le runtime ne parle qu'à une seule interface, appelée World, qui couvre stockage, file d'attente, authentification et streaming. On y branche ce qu'on a déjà : Redis ou Kafka pour les flux, Postgres, Turso, Durable Objects ou le système de fichiers pour la durabilité, Vercel Queues, SQS ou Cloudflare Queues pour la file. Changer une couche ne touche pas au code du workflow.
Y compris chez Vercel : le serveur qui porte l'offre gérée est sans état et n'orchestre rien, c'est une API CRUD déployée comme n'importe quelle application. Tout le travail est dans la bibliothèque cliente, publiée sous licence Apache.
La limite est posée franchement par l'auteur : invoquer une étape n'est pas gratuit — réseau, passage en file, écriture durable du résultat — et cela mine la promesse d'un appel de fonction. La v5, en bêta, revendique jusqu'à 5× de mieux sans changer l'API publique ; la v6 vise à étendre ce gain aux mondes tiers.
Source : Vercel, The best workflow engine is a programming language