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

kley-cli

v0.14.0

Published

The simple local package manager for npm (JS/TS)

Readme

📦 kley

Release Platform npm Crates.io License: MIT

English | Русский

Glue your local packages together without npm publishing, links, or monorepo gymnastics

Like npm link, but with a more convenient workflow. Like yalc, but without the dependency on Node.js.

kley is a command-line tool that simplifies local development of npm packages. It provides a robust alternative to npm link by managing a local package store. It saves packages to a central cache on your machine when you "publish" and lets you quickly install them into your local projects via direct file copying or symlinks, without needing to connect to a remote repository.

Key Features

  • Fast and Efficient: All operations are local, with no network latency or unnecessary publishing of intermediate versions.
  • Reliable and Independent: Avoids npm link issues and works even if your library and projects use different versions of Node.js.
  • Safe by design: Works with files directly, minimizing package script execution.
  • Simple API: Two core commands to get started: publish and install.
  • Cross-Platform: Works on macOS, Linux, and Windows.

Getting started

If your goal is simply to use a locally built package, two commands are enough: publish and install. Let's walk through the basic scenario:

Steps:

  1. In your library directory — run kley publish: copies package files to kley registry.
  2. In your project directory — run kley install <name>: copies files to .kley/, updates kley.lock, and automatically runs the native package manager to install the package into node_modules/.
  3. Make changes in your library, then run kley publish --push: updates all linked projects.

kley demo scenario 0

The diagram below shows the key steps: publishing, installing the dependency, and then pushing an update.

sequenceDiagram
    actor Dev
    participant Lib as test-lib
    participant Store as ~/.kley
    participant App as test-app

    Note over Dev, App: Initial State: `test-lib` and `test-app` are separate projects.

    Dev->>Lib: 1. `kley publish`
    Lib->>Store: Copies files to registry

    Dev->>App: 2. `kley install test-lib`
    App->>Store: Reads package from registry
    Store-->>App: Copies files to `test-app/.kley/test-lib`
    App->>App: Runs `npm install .kley/test-lib` (or pnpm/yarn)
    App->>App: Updates `package.json` and installs into `node_modules/`

    Note over Dev, App: `test-lib` is now usable in `test-app`. No manual `npm install` needed.

    Dev->>Lib: 3. Makes code changes...
    Dev->>Lib: 4. `kley publish --push`
    Lib->>Store: Copies updated files to registry
    Store->>App: Pushes updates directly to `test-app/.kley/test-lib`

    Note over Dev, App: `test-app` is now running the latest code automatically!

Scenario 1: Robust Workflow publish->add->npm i

This is a more controlled workflow. It's perfect for when you prefer the traditional npm install flow, but want to move faster without publishing to a remote repository.

Steps:

  1. In your library directory — run kley publish: copies package files to kley registry.
  2. In your project directory — run kley add <name>: copies files to .kley/ and updates package.json.
  3. Run npm install, npm creates node_modules/<name> from .kley/<name>.
  4. Make changes in your library, then run kley publish --push: updates all linked projects. Or just kley publish, but in this case you'll also need to run kley update in the project directory to get the changed version.
  5. Run npm install. You can now use the project with the updated library.

kley demo scenario 1

The diagram below shows the key steps: publishing, adding the dependency, and then pushing an update.

sequenceDiagram
    actor Dev
    participant Lib as test-lib
    participant Store as ~/.kley
    participant App as test-app

    Note over Dev, App: Initial State: `test-lib` and `test-app` are separate projects.

    Dev->>Lib: 1. `kley publish`
    Lib->>Store: Copies files to registry

    Dev->>App: 2. `kley add test-lib`
    App->>Store: Reads package from registry
    Store-->>App: Copies files to `test-app/.kley/test-lib`
    App->>App: Modifies `package.json` to point to `file:.kley/test-lib`

    Dev->>App: 3. `npm install`
    App->>App: `npm` creates symlink:<br/>`node_modules/test-lib` -> `.kley/test-lib`

    Note over Dev, App: `test-lib` is now usable in `test-app`.

    Dev->>Lib: 4. Makes code changes...
    Dev->>Lib: 5. `kley publish --push`
    Lib->>Store: Copies updated files to registry
    Store->>App: Pushes updates directly to `test-app/.kley/test-lib`

    Note over Dev, App: `test-app` is now running the latest code automatically!

Scenario 2: Direct Source Link with link

This workflow is ideal for rapid, live development. It creates a direct symbolic link from your project's node_modules to your library's source directory. It's the fastest way to see changes, but like npm link, it's less durable.

Steps:

  1. In your library directory — run kley publish: records the source path in the kley registry.
  2. In your project directory — run kley link <name>: creates a symlink directly in node_modules/<name> pointing to your library's source — no npm install needed
  3. Make changes in your library: the project sees them instantly because of the direct link.

⚠️ Note: If you run npm install, it will delete the symlink. Restore it instantly with kley install or kley link <name> again.

kley demo scenario 2

This diagram shows how kley link provides a direct connection to the source.

sequenceDiagram
    actor Dev
    participant Lib as test-lib (source)
    participant Store as ~/.kley (registry)
    participant App as test-app

    Note over Dev, App: Prerequisite: `test-lib` has been published (source path recorded).

    Dev->>App: 1. `kley link test-lib`
    App->>Store: Gets source path for `test-lib`
    Store-->>App: Returns `/path/to/test-lib`
    App->>App: Creates symlink:<br/>`node_modules/test-lib` -> `/path/to/test-lib`

    Note over Dev, App: `test-lib` is now linked directly to source.

    Dev->>Lib: 2. Makes code changes...
    Note over Dev, App: `test-app` sees changes instantly!

Quick pick: Not sure which workflow to use?

| | Scenario 1 publish→add→npm i | Scenario 2 publish→link | |---|---|---| | Best for | Stable, ongoing development | Quick, temporary testing | | Modifies package.json | Yes | No | | Requires npm install | Yes | No | | Survives npm install | Yes | No. Run kley link again |

Installation

Quick Install (recommended)

You can install kley with a single command using the installer script.

Linux / macOS:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/sumbad/kley/releases/latest/download/kley-installer.sh | sh

Windows:

powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; irm https://github.com/sumbad/kley/releases/latest/download/kley-installer.ps1 | iex"

Manual Installation

Alternatively, you can install kley by downloading a pre-compiled binary from the Releases page.

  1. Download the appropriate archive for your system (e.g., kley-x86_64-apple-darwin.tar.gz).
  2. Unpack the archive.
  3. Move the kley binary to a directory in your system's PATH (e.g., /usr/local/bin on macOS/Linux).

Install via npm (kley-cli)

⚠️ Note: The npm package wraps the kley binary and requires Node.js to run. If your library and consuming project use different Node.js versions, prefer the binary installer or Cargo install instead.

npm install -g kley-cli

Install via Cargo (crates.io)

If you have Rust and Cargo installed, you can install kley directly from crates.io:

cargo install kley

Usage

1. kley publish

Run this command in the directory of the package you want to share locally. Kley copies all necessary files to a central store at ~/.kley/packages/<your-package-name>.

  • Use the --push flag to automatically update the package in all projects where it has been added or linked. This is the primary command for a fast, iterative workflow.

2. kley unpublish

Run this command in the directory of a published package to remove it from the kley store.

  • By default, it performs a "soft" unpublish, removing the package from the store but leaving your projects intact until the next install.
  • Use the --push flag to perform a "hard" unpublish, which also removes the package from all projects that use it.

3. kley install [package-name] (alias i)

A universal command that combines add and the native package manager installation. It automatically detects whether your project uses npm, pnpm, or yarn, copies the package to .kley/, updates kley.lock, and delegates the installation to the appropriate package manager — all in one go.

  • With a package name: kley install <package-name> installs the specified package from the local registry.
  • Without a package name: kley install installs all packages listed in kley.lock. This is useful for restoring all local dependencies, similar to how npm install refreshes node_modules based on package.json. Packages already in devDependencies are automatically installed with the appropriate dev flag.
  • Link restoration: If a package was added via kley link, kley install (without arguments) will automatically restore the direct symlink to the source directory if it's missing (e.g., after npm install).
  • Use the --dev or -D flag to install a package as a devDependency: kley install --dev <package-name>.
  • Use the --no-save flag to install a package into node_modules/ and update kley.lock without modifying package.json. This is useful for temporary testing and also works with kley install --no-save (no package name) to restore all packages from kley.lock. Note: Yarn v1 does not support this flag natively and will still modify package.json.
  • Supports npm, pnpm, and yarn out of the box.
  • To explicitly specify the package manager, set the packageManager field in package.json or kley.lock.
  • Fast reinstall: When a package's dependencies and peerDependencies haven't changed since the last install, kley skips the package manager entirely and copies files directly to node_modules/<pkg>. This makes iterative workflows (repeated kley publishkley install) significantly faster.
  • Faster install for packages without dependencies: When a package has no dependencies and peerDependencies, kley skips the package manager entirely and creates a direct symlink to node_modules/<pkg>. This is even faster than the normal "fast reinstall" and is ideal for simple utility packages or components.
  • Lifecycle scripts (preinstall, install, postinstall) are disabled by default (--ignore-scripts) for safety. This prevents arbitrary code execution during install. If a package requires lifecycle scripts to function (e.g., native modules), run the package manager manually.

4. kley add <package-name>

Run this command in the project where you want to use your local package. Kley copies the package into a local ./.kley/ directory, then automatically updates your package.json and kley.lock.

  • Use the --dev flag to add the package to devDependencies.

Note: For the changes to appear in node_modules, you must run npm install (or yarn, pnpm) after kley add. For a one-step alternative, use kley install.

5. kley link <package-name>

This command provides a flexible workflow that avoids modifying package.json. It creates a symbolic link from your project's node_modules directly to the library's source directory.

  • Live updates: Changes in the library are visible immediately without needing to re-publish or re-install.
  • Singleton warning: If the package has dependencies that are also listed as peerDependencies (e.g., React), kley will issue a warning. Linking such packages may cause duplicate instances if they are also dependencies of other packages in your project. In such cases, kley install is recommended instead.

Warning: Because package.json is not modified, running npm install (or yarn, pnpm) will delete the symlink from node_modules. To restore it, simply run kley install (to restore all) or kley link <package-name> again.

6. kley update [package-name]

This command updates installed packages to the latest version from the kley store.

  • If you provide a package name, only that specific package will be updated.
  • If you run it without arguments, kley will update all packages listed in kley.lock.
  • Note: Linked packages are skipped during update because they point directly to the source.

7. kley remove [package-name]

Run this command to cleanly remove a kley-managed dependency from your project. It will update package.json and kley.lock, and delete the package files from the ./.kley/ directory.

  • Use the --all flag to remove all kley-managed packages from the project.

Note: When copying a package into your project, kley automatically strips its devDependencies from package.json. This keeps your node_modules lean and speeds up installation. The original package in the kley registry remains unchanged.

8. kley watch [path]

Run this command in the directory of your local package to monitor files for changes and automatically run kley publish --push whenever changes are detected. This enables a seamless hot-reloading development workflow where the consuming projects receive updates instantly.

  • With a path: kley watch <path> (e.g., kley watch src) only monitors the specified subdirectory for changes. This is highly recommended for large projects to reduce file system watcher load.
  • Without a path: kley watch monitors the entire package directory (excluding node_modules, .git, and .kley directories automatically).

Publish hooks

By default kley publish is a pure file copy — it never runs package.json lifecycle scripts. This keeps you safe from accidental side effects (e.g. a hook that publishes to the real npm registry). To run build/prep steps during publish, configure explicit hooks in .kley/hooks.json:

  • On the first kley publish an interactive wizard lists the npm lifecycle scripts found in your package.json (prepare, prepack, prepublishOnly, postpack, publish, postpublish) and lets you choose which to run. The selection is saved to .kley/hooks.json.
  • Hooks run only from .kley/hooks.json. kley never reads package.json scripts at publish time.
  • .kley/hooks.json is yours to edit freely. A hook command does not have to mirror the script in package.json — you can copy the original command, tweak it (add flags, change the script), save the file, and exactly that command runs. kley executes the command as written in hooks.json, never the package.json one.
  • PRE hooks run before files are copied; POST hooks run after. If a hook fails, kley publish aborts (a failing pre-hook means nothing is copied).
kley publish                    # wizard on first run, then runs configured hooks
kley publish -y                # alias for --non-interactive: no wizard; hooks run only if .kley/hooks.json exists
kley publish --no-hooks         # ignore .kley/hooks.json this run (pure copy)
kley hooks list                 # show the current .kley/hooks.json
kley hooks edit                 # re-run the wizard (keeps manually-added hooks)

Safety: hooks are executed exactly as written in .kley/hooks.json. Review them carefully — kley will not guard against dangerous commands such as npm publish.

Benchmarks

Compare kley against yalc and @jimsheen/yalc in two typical scenarios: cold start and iterative development.

| Operation | kley | yalc | @jimsheen/yalc | | -------------------------------- | --------- | ------- | -------------- | | Cold start (publish → install) | ~9 ms | ~390 ms | ~437 ms | | Iteration (publish --push) | ~7 ms | ~106 ms | ~125 ms |

Prerequisites

To run all benchmarks (including yalc tools), install the required Node.js packages once:

npm install --prefix target/bench_deps yalc @jimsheen/yalc

Then export the paths:

export BENCH_YALC_JS=$PWD/target/bench_deps/node_modules/yalc/src/yalc.js
export BENCH_JIMSHEEN_YALC_JS=$PWD/target/bench_deps/node_modules/@jimsheen/yalc/dist/yalc.js

Running

Run all benchmarks:

cargo bench --bench publish_install

Run only kley benchmarks (no env vars required):

cargo bench --bench publish_install -- kley

Filter by scenario:

cargo bench --bench publish_install -- cold_start
cargo bench --bench publish_install -- iteration_push

Environment Variables

| Variable | Default | Description | |---|---|---| | KLEY_HOME | ~ (home directory) | The directory where kley stores its registry ($KLEY_HOME/.kley/). By default, kley uses your system's home directory. Override this to store the registry in a custom location (e.g., for CI/CD or isolated test environments). | | KLEY_USE_NPM_COMMAND | npm | Override the npm executable path. Useful for testing or when npm is not in PATH. | | KLEY_USE_PNPM_COMMAND | pnpm | Override the pnpm executable path. | | KLEY_USE_YARN_COMMAND | yarn | Override the yarn executable path. |

Contributing

Contributions are welcome! Please feel free to share your feedback and suggestions.

About

This project is inspired by great tools like yalc. The main advantage of kley is that it is a single, self-contained binary with no dependency on Node.js. This means you can manage packages regardless of your current Node.js version or any issues with npm itself.

License

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