React library for viewing AWS Step Functions workflows in the browser
npm install asl-viewer




A React library for visualizing AWS Step Functions workflows (Amazon States Language) in the browser. Built with TypeScript and based on the AWS Toolkit for VS Code.
Check out our Storybook to see interactive examples and explore all available components and features.
GIF Examples
- 🎨 Visual Workflow Rendering - Display ASL workflows as interactive graphs
- 🌓 Theme Support - Light and dark themes built-in
- 📐 Layout Options - Support for Top-to-Bottom and Left-to-Right layouts
- ✅ ASL Validation - Comprehensive validation for ASL syntax and semantics
- 🔄 Auto Layout - Automatic graph layout with reactive updates
- 📱 Responsive - Works on different screen sizes
- 🖱️ Interactive - Click handlers for states and connections
- 🔍 Detailed Inspection - Rich state details panel with JSON viewing
- 🌐 Multiple Input Sources - Load from definition objects, URLs, or files
- 📄 YAML Support - Support for both JSON and YAML formats
- 🔧 Extensible - Easy to customize and extend
- 📚 TypeScript - Full TypeScript support with comprehensive types
``bash`
npm install asl-viewer
or with Yarn:
`bash`
yarn add asl-viewer
Important: You must import the CSS file for the component to display correctly.
`js`
import "asl-viewer/dist/index.css";
`js`
require("asl-viewer/dist/index.css");
`html`
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/asl-viewer@latest/dist/index.css"
/>
If you're using CSS-in-JS libraries or have build tools that don't handle CSS imports automatically, make sure to include the CSS file in your build process or import it in your main application file.
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Required CSS import
const workflow = {
Comment: "A simple minimal example",
StartAt: "Hello",
States: {
Hello: {
Type: "Task",
Resource: "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
End: true,
},
},
};
function App() {
return (
theme="light"
width={800}
height={600}
/>
);
}
`
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Required CSS import
function App() {
return (
theme="light"
width={800}
height={600}
onLoadStart={() => console.log("Loading...")}
onLoadEnd={() => console.log("Loaded!")}
onLoadError={(error) => console.error("Error:", error)}
/>
);
}
`
`tsx
import React, { useState } from "react";
import { WorkflowViewer, FileUploader } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Required CSS import
function App() {
const [selectedFile, setSelectedFile] = useState
return (
$3
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";const yamlWorkflow =
;function App() {
function App() {
return (
definition={yamlWorkflow}
theme="light"
width={800}
height={600}
/>
);
}
`$3
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";function App() {
return (
definition={workflow}
theme="light"
width={900}
height={700}
readonly={false}
isDraggable={true}
isSelectable={true}
isMultiSelect={true}
useMiniMap={true}
useControls={true}
onStateClick={(state) => {
console.log("State clicked:", state);
}}
/>
);
}
`$3
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";function App() {
return (
definition={workflow}
theme="light"
width={800}
height={600}
readonly={true}
useControls={false}
useMiniMap={false}
isDraggable={false}
isSelectable={false}
useZoom={false}
/>
);
}
`$3
`tsx
import React from "react";
import { WorkflowViewer } from "asl-viewer";function App() {
return (
definition={complexWorkflow}
theme="dark"
width={1000}
height={800}
useMiniMap={true}
useControls={true}
useFitView={true}
useZoom={true}
/>
);
}
`Supported Formats
ASL Viewer supports multiple input formats and sources:
$3
- Definition Object: Pass ASL definition directly as JavaScript object
- URL: Load from any accessible URL (supports CORS)
- File Upload: Upload local JSON or YAML files via file picker or drag & drop
$3
- JSON: Standard ASL format as used by AWS Step Functions
- YAML: Human-readable YAML format with same structure as JSON
$3
The library automatically detects format based on:
- File extension (
.json, .yaml, .yml)
- MIME type (application/json, application/yaml, text/yaml)
- Content analysis (fallback parsing)$3
`bash
JSON format
{
"Comment": "A simple workflow",
"StartAt": "FirstState",
"States": {
"FirstState": {
"Type": "Pass",
"End": true
}
}
}YAML format
Comment: "A simple workflow"
StartAt: "FirstState"
States:
FirstState:
Type: "Pass"
End: true
`API Reference
$3
| Prop | Type | Default | Description |
| ------------------- | ---------------------------------- | --------- | ------------------------------------------- |
|
definition | ASLDefinition \| string | - | The ASL workflow definition (JSON or YAML) |
| url | string | - | URL to load the ASL definition from |
| file | File | - | File object containing the ASL definition |
| theme | 'light' \| 'dark' | 'light' | Visual theme |
| layoutDirection | 'TB' \| 'LR' | 'TB' | Layout direction (Top-Bottom or Left-Right) |
| width | number | 800 | Viewer width in pixels |
| height | number | 600 | Viewer height in pixels |
| readonly | boolean | true | Whether the viewer is read-only |
| isConnectable | boolean | true | Whether nodes can be connected |
| isDraggable | boolean | false | Whether nodes can be dragged |
| isSelectable | boolean | true | Whether nodes can be selected |
| isMultiSelect | boolean | false | Whether multiple nodes can be selected |
| useMiniMap | boolean | false | Whether to show navigation minimap |
| useControls | boolean | true | Whether to show zoom/pan controls |
| useZoom | boolean | true | Whether zooming is enabled |
| useFitView | boolean | true | Whether to auto-fit view to show all nodes |
| showToolbar | boolean | false | Whether to show the toolbar |
| hideComment | boolean | false | Whether to hide the workflow comment |
| onStateClick | (state: StateNode) => void | - | Callback when a state is clicked |
| onValidationError | (error: ValidationError) => void | - | Callback for validation errors |
| onLoadStart | () => void | - | Callback when loading starts |
| onLoadEnd | () => void | - | Callback when loading completes |
| onLoadError | (error: Error) => void | - | Callback when loading fails |
| className | string | - | Additional CSS class names |
| style | React.CSSProperties | - | Inline styles for the root container |Note: You must provide exactly one of
definition, url, or file.Usage Modes
$3
Enable full interactivity with draggable nodes, multi-selection, and comprehensive controls:
`tsx
definition={workflow}
readonly={false}
isDraggable={true}
isSelectable={true}
isMultiSelect={true}
useMiniMap={true}
useControls={true}
onStateClick={(state) => console.log("Clicked:", state)}
/>
`$3
Perfect for presentations or documentation with minimal UI:
`tsx
definition={workflow}
readonly={true}
useControls={false}
useMiniMap={false}
isDraggable={false}
isSelectable={false}
useZoom={false}
/>
`$3
Ideal for complex workflows with enhanced navigation features:
`tsx
definition={largeWorkflow}
useMiniMap={true}
useControls={true}
useFitView={true}
useZoom={true}
width={1000}
height={800}
/>
`$3
Display the workflow from left to right instead of top to bottom:
`tsx
definition={workflow}
layoutDirection="LR"
width={1000}
height={600}
/>
`$3
Compact view for embedding in dashboards or smaller spaces:
`tsx
definition={simpleWorkflow}
width={400}
height={300}
useControls={false}
useMiniMap={false}
useFitView={true}
/>
`$3
| Prop | Type | Default | Description |
| -------------- | ---------------------- | -------------------- | -------------------------------- |
|
onFileSelect | (file: File) => void | required | Callback when a file is selected |
| theme | ViewerTheme | required | Theme object for styling |
| accept | string | ".json,.yaml,.yml" | File types to accept |
| disabled | boolean | false | Whether the uploader is disabled |
| className | string | - | Additional CSS class names |
| style | React.CSSProperties | - | Inline styles |$3
| Prop | Type | Default | Description |
| ------------- | ----------------------- | ---------------------------------- | ------------------------------ |
|
onUrlSubmit | (url: string) => void | required | Callback when URL is submitted |
| theme | ViewerTheme | required | Theme object for styling |
| disabled | boolean | false | Whether the input is disabled |
| placeholder | string | "Enter URL to ASL definition..." | Placeholder text |
| className | string | - | Additional CSS class names |
| style | React.CSSProperties | - | Inline styles |$3
`tsx
import type {
ASLDefinition,
StateDefinition,
StateType,
ValidationError,
WorkflowViewerProps,
ViewerTheme,
StateNode,
} from "asl-viewer";
`$3
`tsx
import {
validateASLDefinition,
parseASLDefinition,
createGraphLayout,
loadFromURL,
loadFromFile,
parseDefinitionString,
} from "asl-viewer";// Validate an ASL definition
const errors = validateASLDefinition(workflow);
// Load from URL
const workflowFromUrl = await loadFromURL("https://example.com/workflow.json");
// Load from file
const workflowFromFile = await loadFromFile(file);
// Parse string (JSON or YAML)
const workflowFromString = parseDefinitionString(yamlOrJsonString);
// Parse and get structured data
const parsed = parseASLDefinition(workflow);
// Create custom layout
const layout = createGraphLayout(parsed.nodes, parsed.connections);
`Supported ASL Features
- ✅ Task States - Lambda functions, activities, and other tasks
- ✅ Choice States - Conditional branching with choice rules
- ✅ Pass States - Data transformation and flow control
- ✅ Wait States - Delays and timeouts
- ✅ Succeed/Fail States - Terminal states
- ✅ Parallel States - Concurrent execution branches
- ✅ Map States - Iteration over arrays (basic support)
- ✅ Retry/Catch - Error handling configuration
- ✅ Input/Output Processing - Path expressions and filters
Feature Configuration
$3
Control user interactions with the workflow:
`tsx
// Enable all interactive features
definition={workflow}
readonly={false}
isDraggable={true} // Drag nodes around
isSelectable={true} // Click to select nodes
isMultiSelect={true} // Select multiple nodes
isConnectable={true} // Connect nodes (if applicable)
/>// Read-only with selection only
definition={workflow}
readonly={true}
isSelectable={true}
isDraggable={false}
isMultiSelect={false}
/>
`$3
Configure zoom, pan, and navigation features:
`tsx
// Full navigation controls
definition={workflow}
useControls={true} // Show zoom/pan buttons
useZoom={true} // Enable zoom functionality
useFitView={true} // Auto-fit content to view
useMiniMap={true} // Show minimap for navigation
/>// Minimal navigation
definition={workflow}
useControls={false}
useZoom={false}
useFitView={true}
useMiniMap={false}
/>
`$3
Handle user interactions and loading events:
`tsx
definition={workflow}
onStateClick={(state) => {
console.log("State clicked:", state.name, state.type);
// Handle state selection, show details, etc.
}}
onValidationError={(error) => {
console.error("Validation error:", error.message);
// Handle validation errors
}}
onLoadStart={() => {
console.log("Loading workflow...");
// Show loading indicator
}}
onLoadEnd={() => {
console.log("Workflow loaded successfully");
// Hide loading indicator
}}
onLoadError={(error) => {
console.error("Failed to load workflow:", error);
// Show error message
}}
/>
`Examples
Check out the
/examples directory for complete usage examples:- Simple React App
- Complex Workflows
- Parallel Execution
Development
$3
`bash
git clone
cd asl-viewer
yarn install
`$3
`bash
yarn build
`$3
Run Storybook locally for development:
`bash
yarn storybook
`Build Storybook for production:
`bash
yarn build-storybook
`The Storybook is automatically deployed to GitHub Pages at https://cleissonb.github.io/asl-viewer/ when changes are pushed to the main branch.
$3
`bash
yarn test
`Customization
$3
#### Example 1:
`tsx
import { WorkflowViewer, getTheme } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Don't forget the CSS importconst customTheme = {
...getTheme("light"),
nodeColors: {
...getTheme("light").nodeColors,
taskState: "#ff6b6b",
choiceState: "#4ecdc4",
},
};
;
`#### Example 2:
`tsx
import { WorkflowViewer, createCustomTheme } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Don't forget the CSS importconst customPurple = createCustomTheme("dark", {
name: "customPurple",
background: "#1a0033",
surfaceColor: "#2d1b69",
nodeColors: {
task: "#4c1d95",
choice: "#7c2d12",
succeed: "#065f46",
},
nodeBorderColors: {
task: "#8b5cf6",
choice: "#f59e0b",
succeed: "#10b981",
},
textColor: "#e879f9",
connectionColor: "#c084fc",
tooltipBackground: "#3c004d",
tooltipTextColor: "#f0f0f0",
});
;
`Contributing
1. Fork the repository
2. Create a feature branch:
git checkout -b feature-name
3. Make your changes
4. Add tests for new functionality
5. Run the test suite: yarn test`This project is licensed under the Apache License 2.0 - see the LICENSE file for details.