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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dongtran/flowmotion

v0.8.9

Published

Code-driven animated system flow diagrams for React.

Readme

Flowmotion

Flowmotion is a fork of Simulacrum, packaged for building code-driven animated system flow diagrams.

Github Cover Twitter Header

It's a react based code playground, where you can write TypeScript code and the bundled runtime will execute that code visually. It's a self sustained package and doesn't need any server. All the compilation and execution happens in the browser itself

The complexity around designing a system or software is usually expressed through underwhelming tools. We are used to dragging and dropping boxes, or sometimes use code to automate that.

With flowmotion, you design using code. And you write code only to solve the design problem and nothing else.

https://github.com/user-attachments/assets/18c34417-b822-4af5-a133-213075acf68b

Mental Model

Say you are building a system which has a polling mechanism and it fetches data from one database and updates another. You shouldn't have to write code to create a box for a poller. You should be writing code FOR a poller.

So you might come up with a design like:

  1. For a particular condition, check if database contains what we are looking for. Update it and retrieve it.
  2. If we do get something from first step, add it to another database.

With metz, this is what the code for a poller will look like:

class Poller {
	private ordersTable = new OrdersTable();
	private pollingCollection = new PollingCollection();

	poll() {
		// Step 1
		const updatedOrder = this.ordersTable.updateOne(
			{
				status: 'processing',
			},
			(order) => order.status === 'pending'
		);

		// Step 2
		if (!updatedOrder) {
			return;
		}
		std.log('Got an order!');

		this.pollingCollection.insert({
			id: `poll_${updatedOrder.id}`,
			order_id: updatedOrder.id,
		});
	}
}

And this is what how the runtime will visualise it:

https://github.com/user-attachments/assets/fefe799a-e1f4-4dfe-b196-5c0a205088f4

Features

  • The runtime executes your code on an internal tick, which essentially acts as time. So a method call might happen on tick=1 and a message might be logged at tick=2.
    • Which means you simulate hard to create scenarios, like multiple things happening at the same time.
  • Data gets rendered as a first class citizen. You can design your system along with the data.
    • More importantly, you can show how the data changes throughout a flow.
  • You don't just write code. You write stories to tell how the code should be executed.
    • Stories enable you to view your design from different vantage points.

There are so many more cool features. And you can find all of them in our documentation!

How does it work?

The IDE is backed by monaco and we run the typescript compiler using vfs on a web worker.

When compiling we run the code through our transformer, which in turn converts the code into state-machines.

To be precise, it converts your code into AsyncGenerators where the generator yields one of our instructions.

Sounds fancy, except our instructions are really simple:

export enum MethodRuntimeCommands {
	LOAD = 'load',
	LOG = 'log',
	UNLOAD = 'unload',
	HALT = 'halt',
	NO_OP = 'no_op',
	AWAIT_FLOW = 'await_flow',
}

In turn, the runtime manages all these state machines and their transitions. Take this code for example:

class Main {
	/**
	 * Is reponsible for many important things.
	 */
	hello() {
		const result = this.world('Hello');
		std.log(result);
	}

	/**
	 * Does all the heavy lifting!
	 */
	world(arg: string) {
		return `${arg} World!`;
	}
}

Here's a simplistic view of what it looks like after transformation:

  flowchart TB
    subgraph hello
        direction TB
        load1[LOAD] --> log[LOG]
        log[LOG] --> unload1[UNLOAD]
    end
    subgraph world
        direction TB
        load2[LOAD: string] --> unload2[UNLOAD: string]
    end

    runtime --> hello
    runtime --> world

The runtime maintains a number internally, called currentTick. It also has a function called tick() whose job is to get all the available state machines, and make them transition, together.

When the combined transition of all the state machines is complete, currentTick is incremented. Here's the code if you want to check it out. Or you can read the docs for more.

How does it render?

The runtime comes with a heap and stack. Every object that your code creates is registered with the heap, and every method call is recorded on the stack. The visualisation is simply a rendering of how the heap and stack evolve. For example, if a method calls another, then it'd be reflected on the stack. And this particular state, will be rendered as the signal moving from one node to another on the playground.

Examples

How to set up?

Install all the dependencies using:

yarn install

And once done, you can use Storybook to start playing with the SDK. Simply run:

yarn storybook

This will start running the storybook app on port 6006. Head over to http://localhost:6006 to access all stories.

Off the shelf usage

You can use the app and embed your diagrams anywhere you want. For example:

<iframe width="1200" height="1200" src="https://app.metz.sh/play/0286b754d9e4408ba172e344eeac47b9">
</iframe>

Next Steps

Check out the docs to dig deep into the fundamental concepts and inner workings.

Feel free to join our slack if you have any question.

Or simply start playing with it in the playground!