ncp
Asynchronous, recursive file and directory copying for Node.js, usable as a CLI tool or a simple callback-based API.
Repository Health
Technical Analysis
ncp (“Node cp”) recursively copies files and directories using Node’s core fs and path modules, running copy operations asynchronously and concurrently up to a configurable limit rather than sequentially like a naive cp -r port. It preserves file modes and can optionally dereference symlinks, skip already-up-to-date files by modification time, and pipe file contents through a custom transform stream while copying.
The package ships both a CLI binary (ncp source dest --filter= --limit= --stoponerr) and a programmatic API (require('ncp').ncp(source, dest, options, callback)), making it usable directly from the command line or embedded in build scripts and other Node tooling. It was a widely-used dependency in the pre-fs.promises/fs-extra era for cross-platform recursive copying.
What You Get
- A CLI binary (
ncp) for recursive copies straight from the terminal, with--filter,--limit, and--stoponerrflags - A programmatic
ncp(source, dest, options, callback)API for embedding recursive copy logic in scripts and build tools - Configurable copy filtering via a RegExp or a custom predicate function applied to each file path
- A
transformhook that lets callers pipe file contents through a custom stream (e.g. for on-the-fly text substitution) instead of a raw byte-for-byte copy - Symlink handling with an optional
dereferencemode, plusclobberand modified-time-aware (modified) overwrite controls
Common Use Cases
- Copying a template or fixture directory tree as part of a build or scaffolding script
- Recursively copying build output or static assets between directories in an npm
scriptspipeline - Selectively copying files that match a pattern (e.g. excluding test fixtures or dotfiles) via the
filteroption - Copying only files that have changed since the destination was last updated, using the
modifiedoption to skip untouched files
Under The Hood
Architecture
The entire copy engine lives in a single file, lib/ncp.js, as one exported ncp(source, dest, options, callback) function built from nested closures rather than separate modules or classes. A startCopy/getStats pair walks the tree node by node using fs.lstat/fs.stat, branching into onFile, onDir, or onLink handlers that each recurse back into startCopy for children; a shared started/finished/running counter trio (checked in the cb() callback) is the sole synchronization mechanism that detects when the whole recursive walk has completed. This flat, single-function design keeps the whole traversal easy to hold in your head for a small utility, but every code path (filtering, symlink dereferencing, clobber/modified checks, error aggregation) is threaded through the same closure, so extending behavior means touching the one function rather than composing independent pieces.
Tech Stack
ncp has zero runtime dependencies, relying only on Node’s built-in fs and path modules, and its CLI wrapper (bin/ncp) does manual process.argv parsing rather than pulling in an args-parsing library. Its devDependencies — mocha, rimraf, read-dir-files, all pinned to old minor-version ranges — are test-only. The package.json targets node >=0.10, and the checked-in .travis.yml builds against Node 0.10, 0.12, and io.js, reflecting the package’s 2011-2015 origin and lack of any updates since for modern Node/ESM tooling.
Code Quality
A real test suite exists at test/ncp.js (197 lines) exercising regular-file copying, regex-based filtering, and symlink/broken-symlink fixtures via Mocha and assert, giving the core copy behavior meaningful coverage. Error handling is callback-style: failures are accumulated into an array or written to an options.errs stream rather than thrown, so callers must remember to check the callback’s error argument, and there is no TypeScript, no linter/formatter configuration, and no modern CI (the Travis config is present but stale and would not run against current Node versions).
API Design
The public surface is a single low-ceremony call — ncp(source, dest, [options], callback) — with sensible defaults (clobber on, dereference/modified off) and orthogonal options (filter, transform, limit) that compose without extra setup, plus a CLI (ncp src dest --filter= --limit= --stoponerr) that mirrors the same flags. The tradeoff is an entirely callback-based contract with no native Promise or async/await support, and documentation limited to the README’s option list with no generated API reference or TypeScript types, which raises friction for anyone integrating it into a modern async codebase.
Used by 8 apps in this directory
Blinko
Knowledge Management · Note Taking
A self-hosted, AI-powered card note-taking tool that lets you capture fleeting thoughts instantly and retrieve them with natural language search.
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
melty
Developer Tools · AI Code Assistants · Code Editors
The AI code editor where every chat message is a git commit you can revert, branch, or squash
Novu
Developer Tools
Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.
Refly
No Code Platforms · AI Development · Automation
Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.
Responsively App
Design Tools · Developer Tools
Preview and interact with your responsive web design across every device size simultaneously — no more manual resizing.
Void
AI Code Assistants · Code Editors · Automation
Open-source AI code editor with direct LLM integration and data privacy
Worklenz
Project Management · Product Management · Collaboration
All-in-one open source project management for teams who want full control — plan projects, track tasks, manage resources, and monitor finances without the SaaS lock-in.