# recursive-copy

> Simple, flexible file copy utility

Latest version **2.0.14** (published 2022-02-13) · ISC license · 0 weekly downloads

## Install

```sh
npm install recursive-copy
pnpm add recursive-copy
yarn add recursive-copy
bun add recursive-copy
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.14 |
| Published | 2022-02-13 |
| First published | 2015-05-16 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 9 |
| Unpacked size | 24 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 98 |
| Author | Tim Kendrick |
| Maintainers | timkendrick |
| Keywords | copy, recursive, file, directory, folder, symlink, fs, rename, filter, transform, glob, regex, regexp |

## Links

- npm: https://www.npmjs.com/package/recursive-copy
- Repository: https://github.com/timkendrick/recursive-copy
- Issues: https://github.com/timkendrick/recursive-copy/issues
- npm.io page: https://npm.io/package/recursive-copy

## Dependencies (9)

- [junk](https://npm.io/package/junk.md) ^1.0.1
- [pify](https://npm.io/package/pify.md) ^2.3.0
- [errno](https://npm.io/package/errno.md) ^0.1.2
- [slash](https://npm.io/package/slash.md) ^1.0.0
- [mkdirp](https://npm.io/package/mkdirp.md) ^0.5.1
- [rimraf](https://npm.io/package/rimraf.md) ^2.7.1
- [promise](https://npm.io/package/promise.md) ^7.0.1
- [maximatch](https://npm.io/package/maximatch.md) ^0.1.0
- [graceful-fs](https://npm.io/package/graceful-fs.md) ^4.1.4

## Alternatives

- [unionfs](https://npm.io/package/unionfs.md) — 2.2M weekly downloads
- [path-starts-with](https://npm.io/package/path-starts-with.md) — 35.9K weekly downloads
- [redzip](https://npm.io/package/redzip.md) — 1.2K weekly downloads
- [vscode-anymatch](https://npm.io/package/vscode-anymatch.md) — 848 weekly downloads
- [@ledgerhq/coin-filecoin](https://npm.io/package/@ledgerhq/coin-filecoin.md) — 793 weekly downloads

## Recent versions

- 2.0.14 (latest) — 2022-02-13
- 2.0.13 — 2021-06-27
- 2.0.12 — 2021-06-27
- 2.0.11 — 2020-08-26
- 2.0.10 — 2019-02-06
- 2.0.9 — 2018-02-10
- 2.0.8 — 2017-12-13
- 2.0.7 — 2017-10-24
- 2.0.6 — 2017-02-09
- 2.0.5 — 2016-05-10
- 2.0.3 — 2016-03-13
- 2.0.2 — 2016-01-19
- 2.0.1 — 2016-01-18
- 2.0.0 — 2016-01-18
- 2.0.0-beta — 2016-01-13
- … 12 more at https://npm.io/package/recursive-copy/versions

## README

# recursive-copy
[![npm version](https://img.shields.io/npm/v/recursive-copy.svg)](https://www.npmjs.com/package/recursive-copy)
![Stability](https://img.shields.io/badge/stability-stable-brightgreen.svg)
[![Build Status](https://travis-ci.com/timkendrick/recursive-copy.svg?branch=master)](https://travis-ci.com/timkendrick/recursive-copy)
[![Windows Build Status](https://img.shields.io/appveyor/ci/timkendrick/recursive-copy/master.svg?label=windows%20build)](https://ci.appveyor.com/project/timkendrick/recursive-copy/branch/master)

> Simple, flexible file copy utility


## Features

- Recursively copy whole directory hierarchies
- Choose which files are copied by passing a filter function, regular expression or glob
- Rename files dynamically, including changing the output path
- Transform file contents using streams
- Choose whether to overwrite existing files
- Choose whether to copy system files
- Filters out [junk](https://www.npmjs.com/package/junk) files by default
- Uses [graceful-fs](https://www.npmjs.com/package/graceful-fs) and [mkdirp](https://www.npmjs.com/package/mkdirp) to avoid filesystem errors
- Emits start, finish and error events for each file that is processed
- Optional promise-based interface

## Examples

#### Node-style callback interface

```javascript
var copy = require('recursive-copy');

copy('src', 'dest', function(error, results) {
	if (error) {
		console.error('Copy failed: ' + error);
	} else {
		console.info('Copied ' + results.length + ' files');
	}
});
```

#### Promise interface

```javascript
var copy = require('recursive-copy');

copy('src', 'dest')
	.then(function(results) {
		console.info('Copied ' + results.length + ' files');
	})
	.catch(function(error) {
		console.error('Copy failed: ' + error);
	});
```

#### ES2015+ usage

```javascript
import copy from 'recursive-copy';

try {
	const results = await copy('src', 'dest');
	console.info('Copied ' + results.length + ' files');
} catch (error) {
	console.error('Copy failed: ' + error);
}
```

#### Advanced options

```javascript
var copy = require('recursive-copy');

var path = require('path');
var through = require('through2');

var options = {
	overwrite: true,
	expand: true,
	dot: true,
	junk: true,
	filter: [
		'**/*',
		'!.htpasswd'
	],
	rename: function(filePath) {
		return filePath + '.orig';
	},
	transform: function(src, dest, stats) {
		if (path.extname(src) !== '.txt') { return null; }
		return through(function(chunk, enc, done)  {
			var output = chunk.toString().toUpperCase();
			done(null, output);
		});
	}
};

copy('src', 'dest', options)
	.on(copy.events.COPY_FILE_START, function(copyOperation) {
		console.info('Copying file ' + copyOperation.src + '...');
	})
	.on(copy.events.COPY_FILE_COMPLETE, function(copyOperation) {
		console.info('Copied to ' + copyOperation.dest);
	})
	.on(copy.events.ERROR, function(error, copyOperation) {
		console.error('Unable to copy ' + copyOperation.dest);
	})
	.then(function(results) {
		console.info(results.length + ' file(s) copied');
	})
	.catch(function(error) {
		return console.error('Copy failed: ' + error);
	});
```


## Usage

### `copy(src, dest, [options], [callback])`

Recursively copy files and folders from `src` to `dest`

#### Arguments:

| Name | Type | Required | Default | Description |
| ---- | ---- | -------- | ------- | ----------- |
| `src` | `string` | Yes | N/A | Source file/folder path |
| `dest` | `string` | Yes | N/A | Destination file/folder path |
| `options.overwrite` | `boolean` | No | `false` | Whether to overwrite destination files |
| `options.expand` | `boolean` | No | `false` | Whether to expand symbolic links |
| `options.dot` | `boolean` | No | `false` | Whether to copy files beginning with a `.` |
| `options.junk` | `boolean` | No | `false` | Whether to copy OS junk files (e.g. `.DS_Store`, `Thumbs.db`) |
| `options.filter` | `function`, `RegExp`, `string`, `array` | No | `null` | Filter function / regular expression / glob that determines which files to copy (uses [maximatch](https://www.npmjs.com/package/maximatch)) |
| `options.rename` | `function` | No | `null` | Function that maps source paths to destination paths |
| `options.transform` | `function` | No | `null` | Function that returns a transform stream used to modify file contents |
| `options.results` | `boolean` | No | `true` | Whether to return an array of copy results |
| `options.concurrency` | `number` | No | `255` | Maximum number of simultaneous copy operations |
| `options.debug` | `boolean` | No | `false` | Whether to log debug information |
| `callback` | `function` | No | `null` | Callback, invoked on success/failure |


#### Returns:

`Promise<Array>` Promise, fulfilled with array of copy results:

```json
[
	{
		"src": "/path/to/src",
		"dest": "/path/to/dest",
		"stats": <Stats>
	},
	{
		"src": "/path/to/src/file.txt",
		"dest": "/path/to/dest/file.txt",
		"stats": <Stats>
	},
	{
		"src": "/path/to/src/subfolder",
		"dest": "/path/to/dest/subfolder",
		"stats": <Stats>
	},
	{
		"src": "/path/to/src/subfolder/nested.txt",
		"dest": "/path/to/dest/subfolder/nested.txt",
		"stats": <Stats>
	}
]
```

## Events

The value returned by the `copy` function implements the `EventEmitter` interface, and emits the following events:

| Event | Handler signature |
| ----- | ----------------- |
| `copy.events.ERROR` | `function(error, ErrorInfo)` |
| `copy.events.COMPLETE` | `function(Array<CopyOperation>)` |
| `copy.events.CREATE_DIRECTORY_START` | `function(CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_COMPLETE` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_START` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_SYMLINK_COMPLETE` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_START` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_ERROR` | `function(error, CopyOperation)` |
| `copy.events.COPY_FILE_COMPLETE` | `function(CopyOperation)` |

...where the types referred to in the handler signature are as follows:

### `ErrorInfo`

| Property | Type | Description |
| -------- | ---- | ----------- |
| `src` | `string` | Source path of the file/folder/symlink that failed to copy |
| `dest` | `string` | Destination path of the file/folder/symlink that failed to copy |

### `CopyOperation`

| Property | Type | Description |
| -------- | ---- | ----------- |
| `src` | `string` | Source path of the relevant file/folder/symlink |
| `dest` | `string` | Destination path of the relevant file/folder/symlink |
| `stats ` | `fs.Stats` | Stats for the relevant file/folder/symlink |

---
_Source: https://npm.io/package/recursive-copy · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
