Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.

Repository files navigation

Knarr logo

Playground
npm version npm downloads unpacked size minzipped size
CI license node version

Knarr

Test local npm packages in real apps without npm link, duplicate React, or dirty dependency diffs.

Knarr copies the built package output directly into the consumer app's node_modules/, so your package behaves like the version you would publish to npm. It works well with pnpm, Vite, Next.js, Webpack/rspack, Turbopack, and teams that want local package overrides to stay out of git.

cd my-app
npx knarr use ../my-lib

cd ../my-lib
knarr dev

If you have not installed Knarr globally, use npx knarr dev for the second command too.

Knarr React + Vite + pnpm demo

Who this is for

  • Library and design-system authors testing packages inside real consumer apps
  • React developers avoiding duplicate React instances and invalid hook calls from symlinks
  • pnpm users where npm link or yalc do not match the installed dependency tree
  • Teams that want local package state kept out of commits

Why Knarr?

npm link creates symlinks that can break module resolution: duplicate React instances, peer dependency mismatches, and bundlers that cannot follow links outside the project root. yalc improves this by copying files, but it rewrites consumer dependency specs and usually needs extra watch tooling.

Knarr keeps dependency specs and lockfiles clean. It publishes a local package into ~/.knarr/store/, injects that package into every registered consumer, and can watch, rebuild, and push changes continuously.

Knarr does create a .knarr/ directory in each consumer app for local state, backups, and restore metadata. Setup adds .knarr/ to .gitignore, so that state stays local instead of becoming a committed package override.

Quick Start

One command links a local package into the app you are testing:

# In your app
cd my-app
npx knarr use ../my-lib

Then run the continuous package dev loop from the library:

# In your library
cd ../my-lib
knarr dev

If Knarr is not installed globally, run npx knarr dev instead.

That is the everyday loop: edit my-lib, Knarr rebuilds it, pushes changed files into my-app/node_modules/, and your bundler sees the update.

If you prefer the explicit steps:

cd my-lib
pnpm build
knarr publish

cd ../my-app
knarr add my-lib

How It Works

graph LR
    A["my-lib/"] -- "knarr publish" --> B["~/.knarr/store/<br/>my-lib@1.0.0"]
    B -- "knarr use ../my-lib<br/>or knarr add my-lib" --> C["app/node_modules/<br/>my-lib/"]
    B -- "knarr push" --> D["app-2/node_modules/<br/>my-lib/"]

    style A fill:#2e7d32,stroke:#66bb6a,color:#e8f5e9
    style B fill:#1565c0,stroke:#64b5f6,color:#e3f2fd
    style C fill:#e65100,stroke:#ffb74d,color:#fff3e0
    style D fill:#e65100,stroke:#ffb74d,color:#fff3e0
Loading
  1. publish copies built files to a local store at ~/.knarr/store/
  2. use publishes from a local path and links it into the current app
  3. add links an already-published package from the store
  4. push publishes and copies to all registered consumers
  5. dev watches, builds, publishes, and pushes continuously

At A Glance

npm link yalc Knarr
Mechanism Symlinks Copy + package.json rewrite Copy only
Module resolution Broken (dual instances) Works Works
Git contamination None package.json + .yalc/ None
Bundler HMR Often broken Varies Works
pnpm support Fragile Limited Full
Watch mode None External Built-in
Survives npm install No No knarr restore
Incremental sync N/A Full copy each time mtime + xxhash diff

See detailed comparison for a deeper breakdown.

Migrate From yalc In 60 Seconds

cd my-app
npx knarr migrate
npx knarr use ../my-lib

cd ../my-lib
knarr dev

See Migrating from yalc for the full guide.

Install

pnpm add -g knarr       # or npm, yarn, bun
npx knarr init          # one-off setup for a consumer project

Performance Notes

knarr uses CoW reflinks for instant copy-on-write on APFS/btrfs/ReFS, with automatic fallback. Reflink support is probed once per volume and cached. Incremental sync checks size and mtime first, then falls back to xxhash only when needed, so unchanged files are skipped quickly.

Try It Online

Open Playground - run knarr publish, knarr add, and knarr push in the browser with live HMR preview.

Documentation

Getting Started Install, first use/add cycle, watch mode
Commands Every command, every flag
How It Works Store format, injection, CoW copies
Bundler Guide Vite, Webpack, esbuild, Turbopack setup
Comparison npm link vs yalc vs Knarr
CI/CD Using Knarr in CI pipelines
Monorepo Guide Workspace setup and recursive publish
Troubleshooting Common issues and fixes
FAQ Frequently asked questions
Migrating from yalc Step-by-step migration guide
Architecture Internals for contributors
API Reference Programmatic API (TypeScript)
Examples Try it yourself with real packages
Playground Interactive browser-based playground
Contributing Dev setup and guidelines

Acknowledgments

Knarr and its playground are built on top of excellent open-source projects:

License

MIT

About

Modern local package development tool. Smart file copying into node_modules — no symlinks, no git contamination.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages