A simple utility to quickly replace contents in one or more files
Installations
npm install replace-in-file
Developer Guide
Typescript
Yes
Module System
ESM
Min. Node Version
>=18
Node Version
22.12.0
NPM Version
10.9.0
Score
86.4
Supply Chain
99.1
Quality
87.5
Maintenance
100
Vulnerability
99.6
License
Releases
Contributors
Languages
JavaScript (100%)
Developer
adamreisnz
Download Statistics
Total Downloads
165,365,811
Last Day
36,310
Last Week
1,124,976
Last Month
4,688,779
Last Year
52,570,207
GitHub Statistics
590 Stars
265 Commits
66 Forks
3 Watching
3 Branches
29 Contributors
Package Meta Information
Latest Version
8.3.0
Package Id
replace-in-file@8.3.0
Unpacked Size
270.18 kB
Size
197.05 kB
File Count
23
NPM Version
10.9.0
Node Version
22.12.0
Publised On
17 Dec 2024
Total Downloads
Cumulative downloads
Total Downloads
165,365,811
Last day
-9.9%
36,310
Compared to previous day
Last week
-2.7%
1,124,976
Compared to previous week
Last month
-6.5%
4,688,779
Compared to previous month
Last year
29.2%
52,570,207
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
6
Replace in file
A simple utility to quickly replace text in one or more files or globs. Works synchronously or asynchronously with either promises or callbacks. Make a single replacement or multiple replacements at once.
Index
- Installation
- Basic usage
- Advanced usage
- Replace a single file or glob
- Replace multiple files or globs
- Replace first occurrence only
- Replace all occurrences
- Multiple values with the same replacement
- Custom regular expressions
- Multiple values with different replacements
- Multiple replacements with different options
- Using callbacks for
from
- Using callbacks for
to
- Saving to a different file
- Ignore a single file or glob
- Ignore multiple files or globs
- Allow empty/invalid paths
- Disable globs
- Specify glob configuration
- Making replacements on network drives
- Specify character encoding
- Dry run
- Using custom processors
- Using a custom file system API
- CLI usage
- A note on using globs with the CLI
- Version information
- License
Installation
1# Using npm 2npm i replace-in-file 3 4# Using yarn 5yarn add replace-in-file
Asynchronous replacement
1import {replaceInFile} from 'replace-in-file' 2 3const options = { 4 files: 'path/to/file', 5 from: /foo/g, 6 to: 'bar', 7} 8 9try { 10 const results = await replaceInFile(options) 11 console.log('Replacement results:', results) 12} 13catch (error) { 14 console.error('Error occurred:', error) 15}
Synchronous replacement
1import {replaceInFileSync} from 'replace-in-file' 2 3const options = { 4 files: 'path/to/file', 5 from: /foo/g, 6 to: 'bar', 7} 8 9try { 10 const results = replaceInFileSync(options) 11 console.log('Replacement results:', results) 12} 13catch (error) { 14 console.error('Error occurred:', error) 15}
Return value
The return value of the library is an array of replacement results against each file that was processed. This includes files in which no replacements were made.
Each result contains the following values:
file
: The path to the file that was processedhasChanged
: Flag to indicate if the file was changed or not
1const results = replaceInFileSync({ 2 files: 'path/to/files/*.html', 3 from: /foo/g, 4 to: 'bar', 5}) 6 7console.log(results) 8 9// [ 10// { 11// file: 'path/to/files/file1.html', 12// hasChanged: true, 13// }, 14// { 15// file: 'path/to/files/file2.html', 16// hasChanged: true, 17// }, 18// { 19// file: 'path/to/files/file3.html', 20// hasChanged: false, 21// }, 22// ] 23
To get an array of changed files, simply map the results as follows:
1const changedFiles = results 2 .filter(result => result.hasChanged) 3 .map(result => result.file)
Counting matches and replacements
By setting the countMatches
configuration flag to true
, the number of matches and replacements per file will be counted and present in the results array.
numMatches
: Indicates the number of times a match was found in the filenumReplacements
: Indicates the number of times a replacement was made in the file
Note that the number of matches can be higher than the number of replacements if a match and replacement are the same string.
1const results = replaceInFileSync({ 2 files: 'path/to/files/*.html', 3 from: /foo/g, 4 to: 'bar', 5 countMatches: true, 6}) 7 8console.log(results) 9 10// [ 11// { 12// file: 'path/to/files/file1.html', 13// hasChanged: true, 14// numMatches: 3, 15// numReplacements: 3, 16// }, 17// { 18// file: 'path/to/files/file2.html', 19// hasChanged: true, 20// numMatches: 1, 21// numReplacements: 1, 22// }, 23// { 24// file: 'path/to/files/file3.html', 25// hasChanged: false, 26// numMatches: 0, 27// numReplacements: 0, 28// }, 29// ]
Advanced usage
Replace a single file or glob
1const options = { 2 files: 'path/to/file', 3}
Replace multiple files or globs
1const options = { 2 files: [ 3 'path/to/file', 4 'path/to/other/file', 5 'path/to/files/*.html', 6 'another/**/*.path', 7 ], 8}
Replace first occurrence only
1const options = { 2 from: 'foo', 3 to: 'bar', 4}
Replace all occurrences
Please note that the value specified in the from
parameter is passed straight to the native String replace method. As such, if you pass a string as the from
parameter, it will only replace the first occurrence.
To replace multiple occurrences at once, you must use a regular expression for the from
parameter with the global flag enabled, e.g. /foo/g
.
1const options = { 2 from: /foo/g, 3 to: 'bar', 4}
Multiple values with the same replacement
These will be replaced sequentially.
1const options = { 2 from: [/foo/g, /baz/g], 3 to: 'bar', 4}
Multiple values with different replacements
These will be replaced sequentially.
1const options = { 2 from: [/foo/g, /baz/g], 3 to: ['bar', 'bax'], 4}
Multiple replacements with different options
There is no direct API in this package to make multiple replacements on different files with different options. However, you can easily accomplish this in your scripts as follows:
1const replacements = [ 2 { 3 files: 'path/to/file1', 4 from: /foo/g, 5 to: 'bar', 6 }, 7 { 8 files: 'path/to/file2', 9 from: /bar/g, 10 to: 'foo', 11 } 12] 13 14await Promise.all( 15 replacements.map(options => replaceInFile(options)) 16)
Custom regular expressions
Use the RegExp constructor to create any regular expression.
1const str = 'foo' 2const regex = new RegExp('^' + str + 'bar', 'i') 3const options = { 4 from: regex, 5 to: 'bar', 6}
Using callbacks for from
You can also specify a callback that returns a string or a regular expression. The callback receives the name of the file in which the replacement is being performed, thereby allowing the user to tailor the search string. The following example uses a callback to produce a search string dependent on the filename:
1const options = { 2 files: 'path/to/file', 3 from: (file) => new RegExp(file, 'g'), 4 to: 'bar', 5}
Using callbacks for to
As the to
parameter is passed to the native String replace method, you can also specify a callback. The following example uses a callback to convert matching strings to lowercase:
1const options = { 2 files: 'path/to/file', 3 from: /SomePattern[A-Za-z-]+/g, 4 to: (match) => match.toLowerCase(), 5}
This callback provides for an extra argument above the String replace method, which is the name of the file in which the replacement is being performed. The following example replaces the matched string with the filename:
1const options = { 2 files: 'path/to/file', 3 from: /SomePattern[A-Za-z-]+/g, 4 to: (...args) => args.pop(), 5}
Saving to a different file
You can specify a getTargetFile
config param to modify the target file for saving the new file contents to. For example:
1const options = { 2 files: 'path/to/files/*.html', 3 getTargetFile: source => `new/path/${source}`, 4 from: 'foo', 5 to: 'bar', 6}
Ignore a single file or glob
1const options = { 2 ignore: 'path/to/ignored/file', 3}
Ignore multiple files or globs
1const options = { 2 ignore: [ 3 'path/to/ignored/file', 4 'path/to/other/ignored_file', 5 'path/to/ignored_files/*.html', 6 'another/**/*.ignore', 7 ], 8}
Please note that there is an open issue with Glob that causes ignored patterns to be ignored when using a ./
prefix in your files glob. To work around this, simply remove the prefix, e.g. use **/*
instead of ./**/*
.
Allow empty/invalid paths
If set to true, empty or invalid paths will fail silently and no error will be thrown. For asynchronous replacement only. Defaults to false
.
1const options = { 2 allowEmptyPaths: true, 3}
Disable globs
You can disable globs if needed using this flag. Use this when you run into issues with file paths like files like //SERVER/share/file.txt
. Defaults to false
.
1const options = { 2 disableGlobs: true, 3}
Specify glob configuration
Specify configuration passed to the glob call:
1const options = { 2 3 //Glob settings here (examples given below) 4 glob: { 5 6 //To include hidden files (starting with a dot) 7 dot: true, 8 9 //To fix paths on Windows OS when path.join() is used to create paths 10 windowsPathsNoEscape: true, 11 }, 12}
Please note that the setting nodir
will always be passed as false
.
Making replacements on network drives
To make replacements in files on network drives, you may need to specify the UNC path as the cwd
config option. This will then be passed to glob and prefixed to your paths accordingly. See #56 for more details.
Specify character encoding
Use a different character encoding for reading/writing files. Defaults to utf-8
.
1const options = { 2 encoding: 'utf8', 3}
Dry run
To do a dry run without actually making replacements, for testing purposes. Defaults to false
.
1const options = { 2 dry: true, 3}
Using custom processors
For advanced usage where complex processing is needed it's possible to use a callback that will receive content as an argument and should return it processed.
1const results = await replaceInFile({ 2 files: 'path/to/files/*.html', 3 processor: (input) => input.replace(/foo/g, 'bar'), 4})
The custom processor will receive the path of the file being processed as a second parameter:
1const results = await replaceInFile({
2 files: 'path/to/files/*.html',
3 processor: (input, file) => input.replace(/foo/g, file),
4})
This also supports passing an array of functions that will be executed sequentially
1function someProcessingA(input) { 2 const chapters = input.split('###') 3 chapters[1] = chapters[1].replace(/foo/g, 'bar') 4 return chapters.join('###') 5} 6 7function someProcessingB(input) { 8 return input.replace(/foo/g, 'bar') 9} 10 11const results = replaceInFileSync({ 12 files: 'path/to/files/*.html', 13 processor: [someProcessingA, someProcessingB], 14})
Alongside the processor
, there is also processorAsync
which is the equivalent for asynchronous processing. It should return a promise that resolves with the processed content:
1const results = await replaceInFile({
2 files: 'path/to/files/*.html',
3 processorAsync: async (input, file) => {
4 const asyncResult = await doAsyncOperation(input, file);
5 return input.replace(/foo/g, asyncResult)
6 },
7})
Using a custom file system API
replace-in-file
defaults to using 'node:fs/promises'
and 'node:fs'
to provide file reading and write APIs.
You can provide an fs
or fsSync
object of your own to switch to a different file system, such as a mock file system for unit tests.
- For the asynchronous APIs, the provided
fs
must provide thereadFile
andwriteFile
methods. - For the synchronous APIs, the provided
fsSync
must provide thereadFileSync
andwriteFileSync
methods.
Custom fs
and fsSync
implementations should have the same parameters and returned values as their built-in Node fs
equivalents.
1replaceInFile({ 2 from: 'a', 3 fs: { 4 readFile: async (file, encoding) => { 5 console.log(`Reading ${file} with encoding ${encoding}...`) 6 return 'fake file contents' 7 }, 8 writeFile: async (file, newContents, encoding) => { 9 console.log(`Writing ${file} with encoding ${encoding}: ${newContents}`) 10 }, 11 }, 12 to: 'b', 13})
Or for the sync API:
1replaceInFileSync({ 2 from: 'a', 3 fsSync: { 4 readFileSync: (file, encoding) => { 5 console.log(`Reading ${file} with encoding ${encoding}...`) 6 return 'fake file contents' 7 }, 8 writeFileSync: (file, newContents, encoding) => { 9 console.log(`Writing ${file} with encoding ${encoding}: ${newContents}`) 10 }, 11 }, 12 to: 'b', 13})
CLI usage
1replace-in-file from to some/file.js,some/**/glob.js 2 [--configFile=config.json] 3 [--ignore=ignore/files.js,ignore/**/glob.js] 4 [--encoding=utf-8] 5 [--disableGlobs] 6 [--verbose] 7 [--quiet] 8 [--dry]
Multiple files or globs can be replaced by providing a comma separated list.
The flags --disableGlobs
, --ignore
and --encoding
are supported in the CLI.
The setting allowEmptyPaths
is not supported in the CLI as the replacement is
synchronous, and this setting is only relevant for asynchronous replacement.
To list the changed files, use the --verbose
flag. Success output can be suppressed by using the --quiet
flag.
To do a dry run without making any actual changes, use --dry
.
A regular expression may be used for the from
parameter by passing in a string correctly formatted as a regular expression. The library will automatically detect that it is a regular expression.
The from
and to
parameters, as well as the files list, can be omitted if you provide this
information in a configuration file.
You can provide a path to a configuration file
(JSON) with the --configFile
flag. This path will be resolved using
Node’s built in path.resolve()
, so you can pass in an absolute or relative path.
If you are using a configuration file, and you want to use a regular expression for the from
value, ensure that it starts with a /
, for example:
1{ 2 "from": "/cat/g", 3 "to": "dog", 4}
A note on using globs with the CLI
When using the CLI, the glob pattern is handled by the operating system. But if you specify the glob pattern in the configuration file, the package will use the glob module from the Node modules, and this can lead to different behaviour despite using the same pattern.
For example, the following will only look at top level files:
1{ 2 "from": "cat", 3 "to": "dog", 4}
1replace-in-file ** --configFile=config.json
However, this example is recursive:
1{ 2 "files": "**", 3 "from": "cat", 4 "to": "dog", 5}
1replace-in-file --configFile=config.json
If you want to do a recursive file search as an argument you must use:
1replace-in-file $(ls l {,**/}*) --configFile=config.json
Version information
From version 8.0.0 onwards, this package requires Node 18 or higher. If you need support for older versions of Node, please use a previous version of this package.
As 8.0.0 was a significant rewrite, please open an issue if you run into any problems or unexpected behaviour.
See the Changelog for more information.
License
(MIT License)
Copyright 2015-2024, Adam Reis
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
1 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
Reason
5 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 8
Reason
Found 6/28 approved changesets -- score normalized to 2
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
license file not detected
Details
- Warn: project does not have a license file
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'main'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 8 are checked with a SAST tool
Score
3.8
/10
Last Scanned on 2024-12-16
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to replace-in-file
replace-in-file-webpack-plugin
A webpack plugin to replace strings in file(s) after building
string-replace-webpack-plugin
Replace string tokens in the contents of a file.
file-replace-loader
file-replace-loader is webpack loader that allows you replace files in compile time
replace-in-files
Replace text in one or more files or globs. Works asynchronously with promises.