NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3235 most downloaded on npm
A toolkit for JavaScript codemods
Last release 2 months ago
15 Jul 2026
Release timing varies
gaps range from 2 months to 1.3 years
Nearly every release is documented
notes for 55 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
72 releases · first in 2015
0ced828: Add iterator implementation to Collections
0ced828: Add iterator implementation to Collections
ES6 iterators support the new for..of syntax. Since a Collection wraps an Array, we can lean on ECMAScript's new iterator delegation.
bc1de49: Fix --ignore-pattern not matching files when the source path is relative and starts with ../ (or ./)
Ignore patterns such as **/node_modules/** were silently skipped for files enumerated from a relative source path like ../app/src, because picomatch's ** wildcard does not match across a leading ..//./ traversal segment. The path is now also matched with any leading traversal prefix stripped, so ignore behavior is consistent for relative and absolute source paths.
6c2ff57: Bumps recast to allow parsing of Typescript type arguments on tagged template literals
One column per quarter.
e5fe5be: Bumps recast to resolve a bug where JSX elements are wrapped in two pairs of parenthesis
8f60fbf: Enable async tranformers in test utils. All notable changes to this project will be documented in this file.
Republished with temp dependency properly removed (#638, thanks @trivikr for reporting)
temp dependency properly removed (#638, thanks @trivikr for reporting)pkg.pr.new will now be used to build an npm pakage for each commit to the repo, allowing you to more easily test changes or use new features before an
pkg.pr.new will now be used to build an npm pakage for each commit to the repo, allowing you to more easily test changes or use new features before an official release is cut. (#622, @Aslemammad)temp library with tmp (#633, @r4zendev)docs command from package.json since the new docs are in the website folder, which has instructions in its README.We needed to go from v0.x to a major release, and it may as well happen now. jscodeshift has been around for nine years though, so going to v1.0.0 did
We needed to go from v0.x to a major release, and it may as well happen now. jscodeshift has been around for nine years though, so going to v1.0.0 didn't feel quite right. I've instead promoted the minor version number to a major version number, similar to what React did when it went from 0.14 to 15.0.
importAttributes (#585, @benasher44) and decoratorAutoAccessors (#594, @syi0808) pluginsRemoved old babel-core dependency that was unused but caused security scanners to flag vulnerabilities.
babel-core dependency that was unused but caused security scanners to flag vulnerabilities.Added a --gitignore flag to avoid transforming any files listed in .gitignore (#508, @ElonVolo)
--gitignore flag to avoid transforming any files listed in .gitignore (#508, @ElonVolo)Process all supported extensions by default (#584, @trivikr)
Upgraded to recast 0.23.3 (#564, @ashsearle)
@babel/plugin-proposal-private-methods in worker (#568, @sibelius)Upgraded to recast 0.23.1 (#544, @ryanrhee)
Added a defineSnapshotTestFromFixture test util (#471, @shriuken)
defineSnapshotTestFromFixture test util (#471, @shriuken)renameTo filters for Babel 6+ node types (#412 and #504, @elonvolo and @henryqdineen)childNodesOfType to JSX traversal methods (#415, @j13huang)--help to be listed in an order other than alphabetically, so they can instead be grouped thematically (#507, @elonvolo)j shortcut in test utils (#515, @no23reason)Switched from colors to chalk to mitigate a security vulnerability in colors@1.4.1.
colors to chalk to mitigate a security vulnerability in colors@1.4.1.Full Changelog: https://github.com/facebook/jscodeshift/compare/0.13.0...0.13.1
Added a --fail-on-error flag to return a 1 error code when errors were found (#416, @marcodejongh)
--fail-on-error flag to return a 1 error code when errors were found (#416, @marcodejongh)template.asyncExpression (#405, @jedwards1211)Allow transform to be a Promise (#237, @rektide)
### Changed - Updated recast to latest
recast to latestUpdated flow-parser to latest, and enabled Flow Enums parsing by default when using Flow parser
flow-parser to latest, and enabled Flow Enums parsing by default when using Flow parserNothing published for this version
Dropped support for Node versions 6 and 8
Nothing published for this version
Added jest snapshot utils (#297, @dogoku)
Allow writing tests in TypeScript
.gitingore files: Ignore comments and support \r\n line breaks (#306)Don't throw an error when jscodeshift processes an empty set of files (#295, @skovhus).
renameTo should not rename class properties (#296, @henryqdineen).@babel/register/@babel/preset-env is configured to not transpile any language features that the running Node process supports. That means if you use f
@babel/register/@babel/preset-env is configured to not transpile any
language features that the running Node process supports. That means if you use
features in your transform code supported by the Node version you are running,
they will be left as is. Most of ES2015 is actually supported since Node v6.@babel/register are now properly named and
loaded.Tranform files can be written in Typescript. If the file extension of the transform file is .ts or .tsx, @babel/preset-typescript is used to convert t
.ts or .tsx, @babel/preset-typescript is used to
convert them. This requires the --babel option to be set (which it is by
default). ( #287 , @brieb )babel-preset-es2015 and babel-preset-stage-1 in favor of
@babel/preset-env. Only @babel/proposal-class-properties and
@babel/proposal-object-rest-spread are enabled as experimental features. If
you want to use other's in your transform file, please create a PR.@babel/parser instead of Babylon ( #291, @elliottsj )micromatch => v3.1.10, which doesn't (indirectly) depend on randomatic <
v3 anymore (see #292).Replaces deprecated nomnom with own implementation
A bunch of changes to get jscodeshift in a better shape. This is minor version update because important dependencies and parser configurations have changed.
--parser-config: This option accepts a path to a JSON file and overrides the default options for flow or babylon. This allows you to tweak parser settings (e.g. legacy decorators). (46d250f)--stdin: If provided, the list of files/directories is read from stdin. This makes it easier to pass large lists of files. (b6eaa0a)api.report lets you print arbitrary text to stdout. Useful if another tools consumes jscodeshift's stdout. (c902a00) Example:// In the transform
api.report('some data');
// in stdout
REP path/to/file.js some data
--parser=ts or --parser=tsx.hasAttributes method understands value-less Boolean attributes (#277 , @artemruts )Nothing published for this version
Bump recast and babylon to support JSX fragments
dynamicImport plugin to babylon parser. (#208)some() and every() methods for Collection (#216)renameTo renaming React component prop name unexpectedly (#220)renameTo not taking property shorthands into account (#211)Nothing published for this version
Nothing published for this version
@TheSavior added the possibility to define tests inline, without having to create separate files for input and output:
@TheSavior added the possibility to define tests inline, without having to create separate files for input and output:
const transform = require('../myTransform');
defineInlineTest(transform, {}, 'input', 'expected output');
#204
Printing issues by bumping recast and babylon versions ( #200 , #201 @xixixao)
template.expression when a literal with no interpolation was used ( #196, @jsnajdr)es6-promise ( #189, @wtgtybhertgeghgtwtg)Thank you @xixixao, @jsnajdr and @wtgtybhertgeghgtwtg for contributing!
Write changes to files atomically (#156, @alangpierce)
Collections now have a .length property which is equivalent to .size() (#151, @DrewML)
Collections now have a .length property which is equivalent to .size() (#151, @DrewML)
You can now reference jscodeshift as j directly from the transform's API options. I.e. you can write
export default function transformer(file, { j }) {
return j(file.source).toSource();
}
instead of
export default function transformer(file, api) {
const j = api.jscodeshift;
return j(file.source).toSource();
}
or
export default function transformer(file, {jscodeshift: j}) {
return j(file.source).toSource();
}
(#153, @vjeux)
.editorconfig file ( #142 , @DrewML )
.editorconfig file ( #142 , @DrewML ).get on an empty collection ( #140 , @DrewML )Use all CPUs if only one is available ( #137, @daedalus28 )
Return value of Runner.run includes elapsed time and stats collected via stats method ( #128, @iamdustan).
Runner.run includes elapsed time and stats collected via stats method ( #128, @iamdustan).jscodeshift --version also prints the used recast version ( #131, @keyanzhang)renameTo ignores Identifiers that are not variable references ( #125, Robby Nevels)testUtils supports custom parsers
testUtils supports custom parsers (e5fb37d0c43475fa20181dd542a3a250680138df)testUtils also passes a stub for the stats method to the transformer (e5fb37d0c43475fa20181dd542a3a250680138df)Fixed stats output in dry run. Thanks @gaearon for noticing.
stats output in dry run. Thanks @gaearon for noticing.Fixes an issue with using jscodeshift inside jest unit tests
Seems like npm cannot handle local files (#120) :-/
Seems like npm cannot handle local files (#120) :-/
Problem: jscodeshift uses Babel v5 to parse source files. Since Babel v5 doesn't get updated anymore, jscodeshift is unable to parse files that contai
Problem: jscodeshift uses Babel v5 to parse source files. Since Babel v5 doesn't get updated anymore, jscodeshift is unable to parse files that contain more modern flow type annotation.
To solve this, jscodeshift now supports three parsers, babel v5, babylon and flow, and even allows you to pass your own. Babel v5 still stays the default parser, but we will likely use another parser (babylon or flow) as default in the future. Having the option to pass a custom parser allows us to experiment which works best with jscodeshift/recast.
--parser allows you specify one of the built-in parsers from the command line: --parser=babelv5, --parser=babylon, --parser=flow.
jscodeshift now accepts a second argument that is directly passed to recast's parse method. This allows you to load your own parser, as long as it is compatible with recast:
jscodeshift(source, {parser: require('myParser')})
The value of the parser export of the transformer is used as parser. The value can either be the name of one of the built-in parsers (babel, babylon, flow) or an object that can be directly passed to recast.parse.
Examples:
export const parser = 'flow';
// or
export {default as parser} from 'myParser';
This allows transformers to specify their own parser (as long as it is compatible with ESTree / recast), making them a bit more independent from jscodeshift's internals.
jscodeshift --version now also lists the versions of the built-in parsers
$ jscodeshift --version
jscodeshift: 0.3.21
- babel: 5.8.38
- babylon: 6.8.1
- flow: 0.26.0
Reinstalling jscodeshift is probably the simplest way for now to update the built-in parsers.
--ignore-pattern and --ignore-file command line arguments, which allow you to specify paths to ignore when using jscodeshift to traverse over a dictio
--ignore-pattern and --ignore-file command line arguments, which allow you to specify paths to ignore when using jscodeshift to traverse over a dictionary ( #107 , @chrisdarroch )
jscodeshift.use which you can pass a plugin too. A plugin would a function that accepts a jscodeshift instance and calls registerMethods on it. This allows plugins to be decoupled form jscodeshift. In addition, if .use is called with the same plugin multiple times, subsequent calls are ignored.
Example:
function myPlugin(jscodeshift) {
jscodeshift.registerMethods({
myExtension() { ... },
}, jscodeshift.Identifier);
}
jscodeshift.use(myPlugin);
( #108 , @jamestalmage )
Better registerMethods method! Until now, it was impossible to register two methods with the same name, even if it was attached to different types (and therefore, conceptually, different collections). @jamestalmage changed this in #110 and and now it's possible to register such methods if the types are not super- or sub-types.
Example:
jscodeshift.registerMethods({
rename() { ... },
}, j.Identifier);
jscodeshift.registerMethods({
rename() { ... },
}, j.VariableDeclarator);
Unit tests for transforms: @Daniel15 added helper methods to make writing unit tests easier ( #104 ) . See the readme and the example for more information.
This results in a directory structure like this:
/MyTransform.js /__tests__/MyTransform-test.js /__testfixtures__/MyTransform.input.js /__testfixtures__/MyTransform.output.jsTo define a test, use defineTest from the testUtils module:
jest.autoMockOff(); const defineTest = require('jscodeshift/dist/testUtils').defineTest; defineTest(__dirname, 'MyTransform');
Fixed hanging worker processes under certain conditions (we weren't able to find out the exact reasons but it looks like it involves processing at lea
### Fixes Fixed log output
Fixed log output ( #101 )
Both jscodeshift -t ... foo and jscodeshift -t ... foo/ work now
Both jscodeshift -t ... foo and jscodeshift -t ... foo/ work now ( #100 )
Installation issue (missing module)
process.std vs process.stdout)@iamdustan added supported for passing URLs to -t to load transforms remotely ( #94, #95 )
@iamdustan added supported for passing URLs to -t to load transforms remotely ( #94, #95 )
jscodeshift -t http://path/to/script.js
Note: That script cannot have any external dependencies, it has to be entirely self-contained.
@avikchaudhuri improved invalid symlink handling ( #92 ) and worker performance ( #93 )!
@avikchaudhuri improved invalid symlink handling ( #92 ) and worker performance ( #93 )!
Ignore local .babelrc files. This fixes issues with running jscodeshift on code that was in a project that uses Babel. ( #85 ). Thanks to @sviridov!
Ignore local .babelrc files. This fixes issues with running jscodeshift on code that was in a project that uses Babel. ( #85 ). Thanks to @sviridov!
Fixed filtering for .closest method ( #83). Thanks @juliankrispel!
Fixed filtering for .closest method ( #83). Thanks @juliankrispel!
The --slient / -s option suppresses logging to the console ( #79 , #60 ).
The --slient / -s option suppresses logging to the console ( #79 , #60 ).
--run-in-band option makes jscodeshift execute all transformations in the main process instead of splitting up over multiple workers. Useful for debug
--run-in-band option makes jscodeshift execute all transformations in the main process instead of splitting up over multiple workers. Useful for debugging. (#71, @zertosh)
Fixed promise (chain) returned by .run (#69). The code used to perform an invalid operation which let the promise fail always.
.run (#69). The code used to perform an invalid operation which let the promise fail always.jscodeshift.match and many methods that accept an object as second argument for filtering / pattern matching (e.g. .find) now also accept functions /
jscodeshift.match and many methods that accept an object as second argument for filtering / pattern matching (e.g. .find) now also accept functions / objects containing functions. This allows you to write more complex filters more easily.
Example:
j(source)
.find(j.VariableDeclarator, {id: node => node.name === 'foo' || node.name === 'bar'})
finds all VariableDeclarators whose identifier is either named "foo" or "bar".
jscodeshift switched to jest v0.5.10, which means that tests will only run in Node v4+. jscodeshift will likely continue to function in older Node versions though.
.run returns a promise that is resolved once all workers are done
.run returns a promise that is resolved once all workers are done.at accepts negative indexes to get a collection of a node from the end of the current collection.remove now returns the collection itself
Fix .closest not correctly applying filter argument
.closest not correctly applying filter argument (#41)File extension filter only applies to files in traversed directories, not to directly passed files
esprima-fb dependencybabel-core instead of babelNo worker spawned when using --cpu option.
--cpu option.Your coding agent can read these notes before it upgrades. Set up the MCP server →