Asynchronous recursive file copy utility for Node.js with configurable concurrency and filtering options.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
ncp (Node Copy) is an asynchronous recursive file and directory copying utility for Node.js that serves as a pure JavaScript alternative to the Unix cp -r command. It provides both programmatic API and command-line interface functionality with advanced features like concurrency control, file filtering, streaming transforms, and flexible error handling.
npm install ncpconst ncp = require('ncp').ncp;Alternative import (equivalent):
const ncp = require('ncp');const ncp = require('ncp').ncp;
// Basic file/directory copying
ncp('/path/to/source', '/path/to/destination', function (err) {
if (err) {
return console.error(err);
}
console.log('Copy completed successfully!');
});
// With options
ncp(source, destination, {
filter: /\.js$/, // Only copy .js files
limit: 32, // Higher concurrency
clobber: false, // Don't overwrite existing files
stopOnErr: true // Stop on first error
}, function (err) {
if (err) {
return console.error(err);
}
console.log('Copy completed with options!');
});Asynchronously copies files and directories from source to destination with comprehensive options for controlling the copy behavior.
/**
* Copy files and directories asynchronously
* @param {string} source - Source file or directory path
* @param {string} dest - Destination file or directory path
* @param {function} callback - Completion callback function(err)
*/
function ncp(source, dest, callback);
/**
* Copy files and directories asynchronously with options
* @param {string} source - Source file or directory path
* @param {string} dest - Destination file or directory path
* @param {object} options - Copy options object
* @param {function} callback - Completion callback function(err)
*/
function ncp(source, dest, options, callback);Set global concurrency limit for all ncp operations.
/**
* Global concurrency limit for file system operations
* @type {number}
* @default 16
*/
ncp.limit = 16;Alternative way to access the ncp function.
/**
* Alternative access to the main ncp function
* @type {function}
*/
ncp.ncp;Control which files get copied using regular expressions or custom functions.
/**
* Filter files to be copied
* @typedef {RegExp|function} FilterOption
* @property {RegExp} filter - Regular expression to match file paths
* @property {function} filter - Function(filePath) returning boolean
*/
options.filter;Usage Examples:
// Regular expression filter - only copy .js files
const options = {
filter: /\.js$/
};
// Function filter - copy only files modified in last 24 hours
const options = {
filter: function(filePath) {
const stats = require('fs').statSync(filePath);
const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
return stats.mtime.getTime() > dayAgo;
}
};Apply streaming transformations during the copy process.
/**
* Stream transformation function
* @typedef {function} TransformFunction
* @param {ReadableStream} readStream - Source file read stream
* @param {WritableStream} writeStream - Destination file write stream
* @param {object} file - File metadata object with name, mode, mtime, atime
*/
options.transform;Usage Example:
const options = {
transform: function(readStream, writeStream, file) {
if (file.name.endsWith('.txt')) {
// Transform text files to uppercase
readStream
.pipe(require('stream').Transform({
transform(chunk, encoding, callback) {
callback(null, chunk.toString().toUpperCase());
}
}))
.pipe(writeStream);
} else {
// Copy other files normally
readStream.pipe(writeStream);
}
}
};Control whether to overwrite existing destination files.
/**
* Whether to overwrite existing destination files
* @typedef {boolean} ClobberOption
* @default true
*/
options.clobber;Control how symbolic links are processed during copying.
/**
* Whether to follow symbolic links
* @typedef {boolean} DereferenceOption
* @default false
*/
options.dereference;Set the maximum number of concurrent file system operations.
/**
* Concurrency limit for file system operations
* @typedef {number} LimitOption
* @default 16
* @min 1
* @max 512
*/
options.limit;Control error handling behavior and error output destination.
/**
* Whether to stop on first error
* @typedef {boolean} StopOnErrOption
* @default false
*/
options.stopOnErr;
// Note: The CLI uses --stoponerr but the API uses stopOnErr
/**
* Error output destination
* @typedef {string|Stream} ErrorsOption
* @property {string} errs - File path for error logging
* @property {Stream} errs - Writable stream for error output
*/
options.errs;Transform destination file paths during copying.
/**
* Function to rename destination paths
* @typedef {function} RenameFunction
* @param {string} targetPath - Original destination path
* @returns {string} - Modified destination path
*/
options.rename;Only copy files if source is newer than destination.
/**
* Only copy if source file is newer than destination
* @typedef {boolean} ModifiedOption
* @default false
*/
options.modified;The ncp package includes a command-line tool for file copying operations.
ncp [source] [destination] [--filter=pattern] [--limit=N] [--stoponerr]# Set concurrency limit
--limit=16
# Set filter pattern (RegExp)
--filter=\\.js$
# Stop on first error
--stoponerrCLI Examples:
# Basic copy
ncp /source/path /dest/path
# Copy with concurrency limit
ncp /source/path /dest/path --limit=32
# Copy only JavaScript files
ncp /source/path /dest/path --filter=\\.js$
# Copy with error stopping
ncp /source/path /dest/path --stoponerrThe callback function receives different error types based on the stopOnError option:
/**
* Single error (when stopOnError is true)
* @typedef {Error} SingleError
* @property {string} message - Error description
* @property {string} stack - Error stack trace
*/
/**
* Multiple errors (when stopOnError is false)
* @typedef {Error[]} ErrorArray
* @property {Error[]} errors - Array of error objects
*/Common error conditions that may occur during copying:
dereference: true)Error Handling Examples:
ncp(source, dest, { stopOnErr: false }, function(err) {
if (Array.isArray(err)) {
console.error('Multiple errors occurred:');
err.forEach(function(error) {
console.error('- ' + error.message);
});
} else if (err) {
console.error('Single error:', err.message);
} else {
console.log('Copy completed successfully');
}
});
// Error logging to file
ncp(source, dest, {
stopOnErr: false,
errs: './copy-errors.log'
}, function(err) {
// Errors are also written to copy-errors.log
if (err) {
console.error('Errors occurred, check copy-errors.log');
}
});// Copy only recently modified files
ncp(source, dest, {
filter: function(filePath) {
const stats = require('fs').statSync(filePath);
const hourAgo = Date.now() - (60 * 60 * 1000);
return stats.mtime.getTime() > hourAgo;
},
modified: true // Additional timestamp check
}, callback);// Optimize for large file operations
ncp(source, dest, {
limit: 64, // Higher concurrency
clobber: true, // Overwrite without checks
dereference: false // Don't resolve symlinks
}, callback);// Safe copying with comprehensive error handling
ncp(source, dest, {
clobber: false, // Don't overwrite existing files
modified: true, // Only copy if newer
stopOnErr: false, // Continue on errors
errs: process.stderr, // Log errors to stderr
filter: function(filePath) {
// Skip hidden files and directories
return !require('path').basename(filePath).startsWith('.');
}
}, function(err) {
if (Array.isArray(err)) {
console.log(`Copy completed with ${err.length} errors`);
} else if (err) {
console.error('Copy failed:', err.message);
} else {
console.log('Copy completed successfully');
}
});