npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

asl-viewer

v1.1.0

Published

React library for viewing AWS Step Functions workflows in the browser

Readme

ASL Viewer

CI Storybook asl-viewer npm version npm bundle size License

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.

📖 Live Examples

Check out our Storybook to see interactive examples and explore all available components and features.

ASL Viewer Demo 2

Features

  • 🎨 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

Installation

npm install asl-viewer

or with Yarn:

yarn add asl-viewer

CSS Import

Important: You must import the CSS file for the component to display correctly.

ES Modules / Webpack

import "asl-viewer/dist/index.css";

CommonJS

require("asl-viewer/dist/index.css");

HTML (if using a CDN)

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/asl-viewer@latest/dist/index.css"
/>

CSS-in-JS / Styled Components

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.

Quick Start

Basic Usage with Definition Object

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 (
    <WorkflowViewer
      definition={workflow}
      theme="light"
      width={800}
      height={600}
    />
  );
}

Loading from URL

import React from "react";
import { WorkflowViewer } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Required CSS import

function App() {
  return (
    <WorkflowViewer
      url="https://example.com/workflow.json"
      theme="light"
      width={800}
      height={600}
      onLoadStart={() => console.log("Loading...")}
      onLoadEnd={() => console.log("Loaded!")}
      onLoadError={(error) => console.error("Error:", error)}
    />
  );
}

Loading from File Upload

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<File | null>(null);

  return (
    <div>
      <FileUploader
        onFileSelect={setSelectedFile}
        theme={{
          background: "white",
          borderColor: "#ddd",
          textColor: "#333",
          infoColor: "#007acc",
        }}
      />
      {selectedFile && (
        <WorkflowViewer
          file={selectedFile}
          theme="light"
          width={800}
          height={600}
        />
      )}
    </div>
  );
}

YAML Support

import React from "react";
import { WorkflowViewer } from "asl-viewer";

const yamlWorkflow = `
Comment: "A workflow in YAML format"
StartAt: "HelloWorld"
States:
  HelloWorld:
    Type: "Pass"
    Result: "Hello from YAML!"
    End: true
`;

function App() {
function App() {
  return (
    <WorkflowViewer
      definition={yamlWorkflow}
      theme="light"
      width={800}
      height={600}
    />
  );
}

Interactive Mode with Draggable Nodes

import React from "react";
import { WorkflowViewer } from "asl-viewer";

function App() {
  return (
    <WorkflowViewer
      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);
      }}
    />
  );
}

Presentation Mode (Read-Only)

import React from "react";
import { WorkflowViewer } from "asl-viewer";

function App() {
  return (
    <WorkflowViewer
      definition={workflow}
      theme="light"
      width={800}
      height={600}
      readonly={true}
      useControls={false}
      useMiniMap={false}
      isDraggable={false}
      isSelectable={false}
      useZoom={false}
    />
  );
}

Enhanced Navigation with MiniMap

import React from "react";
import { WorkflowViewer } from "asl-viewer";

function App() {
  return (
    <WorkflowViewer
      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:

Input Sources

  • 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

File Formats

  • JSON: Standard ASL format as used by AWS Step Functions
  • YAML: Human-readable YAML format with same structure as JSON

Content Types

The library automatically detects format based on:

  • File extension (.json, .yaml, .yml)
  • MIME type (application/json, application/yaml, text/yaml)
  • Content analysis (fallback parsing)

Example Files

# 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

WorkflowViewer Props

| 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

Interactive Mode

Enable full interactivity with draggable nodes, multi-selection, and comprehensive controls:

<WorkflowViewer
  definition={workflow}
  readonly={false}
  isDraggable={true}
  isSelectable={true}
  isMultiSelect={true}
  useMiniMap={true}
  useControls={true}
  onStateClick={(state) => console.log("Clicked:", state)}
/>

Presentation Mode

Perfect for presentations or documentation with minimal UI:

<WorkflowViewer
  definition={workflow}
  readonly={true}
  useControls={false}
  useMiniMap={false}
  isDraggable={false}
  isSelectable={false}
  useZoom={false}
/>

Navigation Mode

Ideal for complex workflows with enhanced navigation features:

<WorkflowViewer
  definition={largeWorkflow}
  useMiniMap={true}
  useControls={true}
  useFitView={true}
  useZoom={true}
  width={1000}
  height={800}
/>

Horizontal Layout

Display the workflow from left to right instead of top to bottom:

<WorkflowViewer
  definition={workflow}
  layoutDirection="LR"
  width={1000}
  height={600}
/>

Embedded Mode

Compact view for embedding in dashboards or smaller spaces:

<WorkflowViewer
  definition={simpleWorkflow}
  width={400}
  height={300}
  useControls={false}
  useMiniMap={false}
  useFitView={true}
/>

FileUploader Props

| 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 |

URLInput Props

| 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 |

Types

import type {
  ASLDefinition,
  StateDefinition,
  StateType,
  ValidationError,
  WorkflowViewerProps,
  ViewerTheme,
  StateNode,
} from "asl-viewer";

Utilities

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

Interactive Features

Control user interactions with the workflow:

// Enable all interactive features
<WorkflowViewer
  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
<WorkflowViewer
  definition={workflow}
  readonly={true}
  isSelectable={true}
  isDraggable={false}
  isMultiSelect={false}
/>

Navigation Controls

Configure zoom, pan, and navigation features:

// Full navigation controls
<WorkflowViewer
  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
<WorkflowViewer
  definition={workflow}
  useControls={false}
  useZoom={false}
  useFitView={true}
  useMiniMap={false}
/>

Event Handling

Handle user interactions and loading events:

<WorkflowViewer
  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:

Development

Setup

git clone <repository>
cd asl-viewer
yarn install

Build

yarn build

Storybook

Run Storybook locally for development:

yarn storybook

Build Storybook for production:

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.

Testing

yarn test

Customization

Custom Themes

Example 1:

import { WorkflowViewer, getTheme } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Don't forget the CSS import

const customTheme = {
  ...getTheme("light"),
  nodeColors: {
    ...getTheme("light").nodeColors,
    taskState: "#ff6b6b",
    choiceState: "#4ecdc4",
  },
};

<WorkflowViewer definition={workflow} theme={customTheme} />;

Example 2:

import { WorkflowViewer, createCustomTheme } from "asl-viewer";
import "asl-viewer/dist/index.css"; // Don't forget the CSS import

const 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",
});

<WorkflowViewer definition={workflow} theme={customPurple} />;

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
  6. Submit a pull request

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.