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 devIf you have not installed Knarr globally, use npx knarr dev for the second command too.
- 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 linkor yalc do not match the installed dependency tree - Teams that want local package state kept out of commits
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.
One command links a local package into the app you are testing:
# In your app
cd my-app
npx knarr use ../my-libThen run the continuous package dev loop from the library:
# In your library
cd ../my-lib
knarr devIf 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-libgraph 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
publishcopies built files to a local store at~/.knarr/store/usepublishes from a local path and links it into the current appaddlinks an already-published package from the storepushpublishes and copies to all registered consumersdevwatches, builds, publishes, and pushes continuously
| 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.
cd my-app
npx knarr migrate
npx knarr use ../my-lib
cd ../my-lib
knarr devSee Migrating from yalc for the full guide.
pnpm add -g knarr # or npm, yarn, bun
npx knarr init # one-off setup for a consumer projectknarr 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.
Open Playground - run knarr publish, knarr add, and knarr push in the browser with live HMR preview.
| 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 |
Knarr and its playground are built on top of excellent open-source projects:
- chokidar - file watching
- xxhash-wasm - fast file hashing
- citty - CLI framework
- tsup - TypeScript bundler
- vitest - test runner
- WebContainers - in-browser Node.js runtime
- Vite - frontend tooling
- React - UI framework
- Monaco Editor - code editor
- xterm.js - terminal emulator
- Tailwind CSS - styling

