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

jido

v1.0.4

Published

A CLI tool to automate your development workflows using named flows. Simplifies task automation with readable config and plugin support.

Downloads

32

Readme

Jido

Automate your workflows in a flash


What is Jido?

Jido is a CLI tool for running named workflows, called flows, automating sequences of tasks and improving the developer experience without needing to memorize a bunch of commands or wiring up Makefiles.

Define your flows in a config file jido.config.js in the root directory of your project, and run a specific flow with:

jido flow <flowname>

It's like npm run but cooler.

Installation

You can install jido globally or locally.

Global (Recommended)

npm install -g jido

(OR) Local (Per Project)

npm install --save-dev jido

Then, you're good to go!

Getting Started

Run this to initialize a config:

npx jido init

It creates a basic jido.config.js in your project root.

import { jido } from "jido";

/*
* Define your workflows here.
* Each flow is a series of steps with commands to run and optional hooks (onStart, onSuccess, etc) to execute.
*/

const config = {
  flows: [
    {
      name: "run",
      description: "Run the project",
      steps: [
        {
          run: "npm install",
          onStart: () => console.log("Installing dependencies..."),
          onSuccess: () => console.log("Dependencies installed!")
        },
        {
          run: "npm run dev",
          onStart: () => console.log("Starting dev server...")
        }
      ]
    }
  ]
}

export default jido(config);

Commands

jido flow [flowname]

Runs the named flow as defined in your config:

npx jido flow build

Options:

  • -d, --dry-run: Preview what the flow would do without actually executing it.
npx jido flow build --dry-run

jido list

Lists all available flows defined in jido.config.js:

npx jido list

jido init

Scaffolds a basic jido.config.js in your project root:

npx jido init

Options:

  • -f, --force: Overwrite existing jido.config.js files, if any.
npx jido init --force

Config Format

The jido() function takes an object (the config) as argument, which should be defined as follows:

export default jido({
    flows: [
        {
            name: string,  // Name of the flow
            description?: string,  // Description, what the flow does
            steps: [
                {
                    run: string,  // Command to be run, eg. 'npm run dev'
                    // Optional hooks
                    onStart?: Hook,
                    onSuccess?: Hook,
                    onFailure?: Hook,
                    // Plugins
                    plugins: [
                        {
                            // Optional hooks received through plugins
                            onStart?: Hook,
                            onSuccess?: Hook,
                            onFailure?: Hook,
                        }
                    ],
                }
            ]
        }
    ]
});

Commands are run sequentially. If any command fails, the flow stops immediately.

Writing a Plugin

Jido supports lightweight plugins at the step level, allowing you to inject custom behavior during onStart, onSuccess, and/or onFailure.

A plugin should be a function that returns an object of the type Plugin:

type Plugin = {
    onStart?: Hook;
    onSuccess?: Hook;
    onFailure?: Hook;
};

Basic Plugin Example

Create a file (eg. myPlugin.js):

export const myPlugin = () => ({
    onStart: () => {
        console.log("Plugin: Flow step is starting...");
    },
    onSuccess: () => {
        console.log("Plugin: Step completed successfully!");
    }
});

This plugin exports a function that returns an object containing hooks.

Use it in your jido.config.js as follows:

import { myPlugin } from "./myPlugin.js";

export default jido({
  flows: [
    {
      name: "example",
      steps: [
        {
          run: "echo hello",
          onStart: () => console.log("Echo step started..."),
          plugins: [myPlugin()]
        }
      ]
    }
  ]
});

Plugin as an Object (Not Recommended)

You can also pass a plugin directly as an object:

// Plugin
const myPlugin = {
    onStart: () => {
        console.log("Plugin: Flow step started...");
    },
    onSuccess: () => {
        console.log("Plugin: Step completed successfully!");
    }
};

// jido.config.js
plugins: [myPlugin]  // Directly passes the object, unlike previous example where a function was called to return the object

This works fine, but using functions that return plugin objects is recommended — especially when your plugin logic needs configuration or arguments.

Plugins with arguments

Plugins can be dynamic:

// Plugin
const myPlugin = (name) => ({
    onStart: () => {
        console.log(`Hello, ${name}! Starting the flow step...`);
    }
});

// jido.config.js
plugins: [myPlugin("Bob")]  // Dynamic plugins, hooks dependent on arguments

This pattern keeps your plugins composable, configurable, and scalable.

🧠 Tip

You can enable better IntelliSense by adding this at the top of your plugin file:

/** @type {import("jido-kit/types").Plugin} */

Dry Run Mode

You can simulate a flow with:

npx jido flow build --dry-run

This prints the commands without executing them. Helpful for debugging.

Example Use Cases

  • deploy: Run build scripts and deploy using CLI tools.
  • validate: Combine linting, testing, type checking tools into one command.
  • reset: Clear caches, reinstall steps, reset DB, etc.

You are free to define any set of shell commands that makes sense for your workflow.

FAQ

Yes! It's a JS file, not JSON, so you can use variables, imports, etc.

Not currently. However, you can use types from jido-kit to make custom plugins and build them into JS functions to be used as plugins in your jido config.

Bonus: Type Support (jido-kit)

Install jido-kit for full IntelliSense in VS Code:

npm install --save-dev jido-kit

Then, in your config:

/** @type {import("jido-kit/types").Config} */

export default jido({
    ...
});

Why use Jido?

✅ Clean alternative to npm run clutter ✅ Centralizes all your workflows ✅ Dry-run support for safety ✅ Lightweight and dependency-free core ✅ Config in JS — not YAML or JSON

License

MIT