StepFlow is a library that lets you build data-defined user flows.

User flows are multi-step (or multi-screen) user experiences that drive a user towards an outcome. Common examples are user registrations and store cart checkouts.

StepFlow manages user flows with a data-orientation. At its core, it tracks data dependencies between steps to ensure they work well together and that the final required outcome is always achieved.

The data dependencies also allow StepFlow to generate user experiences. Included in the library is a basic HTML form generator. In the future more actions can be built for other platforms such as iOS and Android.

It is designed to be portable and currently has a Typescript and JavaScript helpers in addition to its native Rust support.

Getting Started

Basic concepts

Flows are both defined and executed within a Session object. It is the main point of integration.


Once a session is defined, a flow only needs to call Session.advance with any new data obtained. Advancing exits the current step and enters the next step. An action is then called to fulfill the data for the new step.

If data is lacking or invalid to either exit the current step or enter the next, the defined action will run on the current step again in hopes of obtaining the data successfully (i.e. user enters different data).


There are 3 parts to defining a flow:

Example client-side flow

This example builds a simple client-side flow that runs in the browser.

Setup the build

Run the following commands in the terminal to get the build environment ready.


# create the directory
mkdir demo
cd demo

# install the basic dependencies
npm init -y
npm install --save-dev webpack webpack-cli stepflow-wasm html-webpack-plugin copy-webpack-plugin serve 

Setup Webpack

We'll use Webpack to simplify building our HTML template. Note that we have our own WebAssembly loader so the Copy Plugin is used to copy the library to the output.

Create the webpack.config.js file in your root directory.


// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
    plugins: [
        // generate an HTML file that loads index.js
        new HtmlWebpackPlugin({
            templateContent: '<form id="form"><div id="flow"></div><input type="submit" /></form>'
    new CopyPlugin({
      patterns: [{from: "node_modules/stepflow-wasm/stepflow.wasm" }]

  // optimize for developing
    mode: "development",
    devtool: "eval-source-map",

Define the user flow

We'll define our flow and session in the file src/index.js. Our simple flow is defined in a JSON format which is used to create the Session.


// src/index.js
const FLOW = {
  // define the steps in the flow
  steps: {
    // the $root step is the parent for all steps
    $root: {
      // we'll have 2 steps in the flow: name and email
      substeps: [ "name", "email" ],

      // when we leave this step, we require these outputs to have been fulfilled
      outputs: ["first_name", "last_name", "email"]

    // define what the name and email steps output
    "name": { outputs: ["first_name", "last_name"] },
    "email": { outputs: ["email"] },
  actions: {
    // we'll use a single global action that generates an HTML form for each step's outputs
    $all: {
      type: "HtmlForm",
      prefixHtml: "<label for='{{name}}'>{{name}}</label>", // each form entry will have a label

Run a Session

We can now create a Session and advance it until the flow is fully executed. At the end, we're guaranteed that the required outputs have been gathered. For this example, we'll use the HtmlFormSession helper which is a light wrapper on top of a Session for HTML forms.

Add the example code to the end of src/index.js.


// APPEND to src/index.js
import { loadStepflowWasm, attachFlowToHtmlForm } from "stepflow-wasm";

// load the WASM library
loadStepflowWasm("stepflow.wasm").then(stepFlowWasm => {
  // the form element along with a child element to the generated form elements
  const formElement = document.getElementById("form");
  const anchorElement = document.getElementById("flow");

  // create the HtmlFormSession
  const formSession = attachFlowToHtmlForm(FLOW, stepFlowWasm, formElement, anchorElement);

  // when done, show the user the data obtained
  formSession.onFinish = (_formSession, data) => { alert(JSON.stringify(data))};

  // advance to the first step

Try it out!

Finally, compile it with webpack with the command npx webpack. You can then open the compiled result in your browser using npx serve dist.

JS/TS API Reference

JSON flow schema

Please look at the Typescript definition.



HTML Form Session


Rust API Reference

Please start with

A server-side example using Warp and Tera templates can be found here