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

@cinfinit/hookflow

v1.0.1

Published

A deterministic, multi-package hook orchestration system for monorepos

Downloads

13

Readme


HookFlow 🪝⚡

NPM version NPM downloads

The hook orchestration system your monorepo didn’t know it desperately needed.

HookFlow is not just another script helper. It’s a deterministic, multi-package hook orchestration system for monorepos — capable of handling preinstall, postinstall, and postbuild hooks safely, predictably, and without conflicts.

Whether you’re juggling Husky, Prisma, Patch-package, or any custom scripts, HookFlow makes sure your hooks run in the right order, in the right place, every time.


Why HookFlow Exists

If you’ve ever had multiple tools trying to run hooks in your monorepo, you know the pain:

  • Husky overwriting other postinstall scripts.
  • Prisma generate failing silently.
  • Patch-package running before dependencies are installed.

HookFlow solves this by:

  • Centralizing hooks across root + packages.
  • Deterministic execution with optional priority.
  • Safe error handling for CI/CD (fail-fast or continueOnError).
  • Future-ready architecture for multiple hook types and per-package orchestration.

In short: no conflicts, no surprises, hooks just work.


Features

  • ✅ Multi-hook type support: preinstall, postinstall, postbuild
  • ✅ Monorepo-friendly: define hooks per package, including root
  • ✅ CLI commands: add, remove, list, run
  • ✅ Hook priorities and deterministic ordering
  • ✅ Optional continueOnError per hook
  • ✅ Auto-generated or user-defined hook IDs
  • ✅ Fully production-ready, zero runtime dependencies (Node.js only)

Installation

npm install --save-dev @cinfinit/hookflow

Or run without installing:

npx hookflow

Configuration (just for info , so that you dont delete hookflowrc.json accidently :| )

HookFlow stores its configuration in .hookflowrc.json at the root of your repo. Don't hack it , not recommended . You can try though and face the mess ;) . Here’s a future-proof schema:

{
  "schemaVersion": 1,
  "packages": {
    ".": {
      "postinstall": [
        { "id": "root-1", "cmd": "husky install", "priority": 10, "continueOnError": true },
        { "id": "root-2", "cmd": "patch-package", "priority": 20 }
      ]
    },
    "packages/api": {
      "postinstall": [
        { "id": "api-1", "cmd": "prisma generate", "priority": 5 }
      ]
    }
  }
}

Notes:

  • . → root package
  • packages/api → relative path to a package
  • priority → optional, default 0
  • continueOnError → optional, default false
  • id → unique hook ID (auto-generated if missing)

CLI Usage

Add a Hook

# Add root hook (auto ID)
npx hookflow add "echo root hook"

# Add root hook with priority & continue-on-error
npx hookflow add "echo important hook" --priority 10 --continue-on-error

# Add package-specific hook
npx hookflow add "echo api hook" --package packages/api --priority 5

# Add with custom hook ID
npx hookflow add "echo migration hook" --id migrate-api --package packages/api

Update a Hook

# Update a hook by its ID
npx hookflow update --id migrate-api --cmd "prisma migrate deploy" --priority 8

Remove a Hook

# Remove a hook by ID
npx hookflow remove --id migrate-api

List Hooks

npx hookflow list

Sample output:

id :hf_773a0483 [.] preinstall → echo hi (priority: 0, continueOnError: false)
id :important-root [.] postinstall → echo important hook (priority: 0, continueOnError: false)
id :api-1 [packages/api] postinstall → echo api hook (priority: 0, continueOnError: false)

Run Hooks

# Run all postinstall hooks
npx hookflow run

# Run a specific hook type
npx hookflow run --type preinstall
  • Hooks execute per package, with cwd set correctly.
  • Fails fast by default.
  • Optional --continue-on-error allows selective continuation.

Error Handling

HookFlow provides clear, CI-friendly output:

[HOOK-FAILED] packages/api :: postinstall
Command: prisma generate
Exit code: 1
Stdout: ...
Stderr: ...
  • continueOnError: true → HookFlow will continue to the next hook
  • Exit codes reflect failures for CI/CD pipelines


Wiring HookFlow into npm Lifecycle Scripts

HookFlow does not replace npm’s lifecycle — it aligns with it.

You explicitly decide which hooks run at which lifecycle stage by wiring HookFlow into your package.json scripts.

Recommended setup

{
  "scripts": {
    "preinstall": "hookflow run --type preinstall",
    "postinstall": "hookflow run --type postinstall"
  }
}

What this means

| npm lifecycle | What runs | | ------------- | ----------------------------------------------------- | | preinstall | All preinstall hooks defined in .hookflowrc.json | | postinstall | All postinstall hooks defined in .hookflowrc.json |

HookFlow:

  • Runs hooks only for the specified type
  • Preserves npm’s lifecycle semantics
  • Avoids accidental or out-of-order execution

Why this is explicit (and intentional)

HookFlow will never guess which hooks to run.

This avoids dangerous behavior like:

  • Running preinstall hooks after dependencies are installed
  • Mixing lifecycle phases unintentionally
  • Breaking CI installs with unexpected commands

If you don’t wire a lifecycle — those hooks simply won’t run.


Advanced usage (optional)

If you want to run hooks manually:

# Run only postinstall hooks
hookflow run --type postinstall

# Run only preinstall hooks
hookflow run --type preinstall

Or, for advanced users only:

# Run all hook types explicitly
hookflow run --all

⚠️ Running all hook types is never the default and must be opt-in.


Use Cases

  1. Monorepo dependency setup – install dependencies + generate Prisma models + apply patches in one flow.
  2. CI/CD pipelines – deterministic hook execution ensures reliable builds.
  3. Custom developer workflows – precommit lint, postinstall scripts, custom postbuild tasks.
  4. Multi-package orchestration – each package can have its own hooks, but all coordinated via a single CLI.

Contributing

HookFlow is open-source and welcomes contributions.

git clone https://github.com/cinfinit/hookflow.git

TL;DR

HookFlow = 🪝 + ⚡ + 😌

  • Centralizes hooks for monorepos
  • Deterministic, safe, CI-friendly
  • Easy CLI to add, remove, list, and run hooks
  • Future-ready for multiple hook types & packages

About the Author 🧑‍💻

HookFlow was created by Cinfinit — a self-proclaimed hook whisperer, monorepo wrangler, and accidental shell script poet. Had to write something , then thought why not something different this time ;)

When not orchestrating hooks across packages or debugging ENOENT errors, Cinfinite enjoys:

  • Writing JavaScript that doesn’t make you want to cry
  • Turning postinstall chaos into deterministic harmony
  • Inventing witty names for developer tools (HookFlow, obviously 😉)
  • Pretending that “priority 10” in JSON is the same as “priority life goals”

philosophy: “If your hooks aren’t flowing, neither are you.” MAY BE , may be not :|


TL;DR

npm controls when HookFlow controls what and how

You wire them together explicitly — no magic, no surprises.