π Pluggable and configurable code transformer with built-in ESLint, Babel and support of js, jsx, typescript, flow, markdown, yaml and json
npm install putout[NPMIMGURL]: https://img.shields.io/npm/v/putout.svg?style=flat&longCache=true
[BuildStatusIMGURL]: https://github.com/coderaiser/putout/workflows/Node%20CI/badge.svg
[NPMURL]: https://npmjs.org/package/putout "npm"
[BuildStatusURL]: https://github.com/coderaiser/putout/actions?query=workflow%3A%22Node+CI%22 "Build Status"
[CoverageURL]: https://coveralls.io/github/coderaiser/putout?branch=master
[CoverageIMGURL]: https://coveralls.io/repos/coderaiser/putout/badge.svg?branch=master&service=github
> **Perfection is finally attained not when there is no longer anything to add,
> but when there is no longer anything to take away.**
>
> (c) Antoine de Saint ExupΓ©ry
πPutout is a JavaScript Linter, pluggable and configurable code transformer, drop-in ESLint replacement with built-in code printer and ability to fix syntax errors. It has a lot of transformations that keeps your codebase in a clean state, removing any code smell and making code readable according to best practices.
The main target is JavaScript, but:
- β
JSX;
- β
TypeScript;
- β
Yaml;
- β
Markdown;
- β
JSON;
- β
Ignore;
are also supported. Here is how it looks like:

Check out couple variants of plugins that does the same: linting debugger statement:
- β SWCLint no-debugger: 49 lines;
- β RSLint no-debugger: 48 lines;
- β ESLint no-debugger: 43 lines;
- β Rome no-debugger: 28 lines;
- β
πPutout remove-debugger: 7 lines:
``js
'use strict';
module.exports.report = () => Avoid 'debugger' statement;
module.exports.replace = () => ({
debugger: '',
});
`
Choose wisely, competitors cannot even fixβ¦ π€«
> If I have seen further, it is by standing upon the shoulders of giants.
>
> (c) Isaak Newton
- πͺ ESLint for stable releases and future proof API.API
- πͺ Babel for amazing documented in Handbook and responsiveness of a team.
- πͺ Prettier for minimalistic options and uniform codestyle.
- πͺ jscodeshift for making codemods simple and popular.
- β ESLint avoids fixes that could change the runtime behavior.
- β Babel produces throw-away code.
- β Prettier is a formatter.
- β jscodeshift has no config and plugins support.
βοΈ πPutout on the other hand can make more drastic code transformations that directly affects your codebase making it a better place to code π».
- β
remove unused variables;for-of variables
- β
remove unused ;typescripts
- β
remove unused types;variables
- β
remove unreferenced ;private fields
- β
remove unused ;expressions
- β
remove unused ;variables
- β
remove useless ;Object.assign()
- β
remove useless ;replace()
- β
remove useless ;map
- β
remove useless ;mapped types
- β
remove useless ;mapping modifiers
- β
remove useless ;continue
- β
remove useless ;operand
- β
remove useless ;array constructor
- β
remove useless ;conditions
- β
remove useless ;type conversion
- β
remove useless ;functions
- β
remove useless ;Array.from
- β
remove useless ;spread
- β
remove useless ;arguments
- β
remove useless ;escape
- β
remove useless ;async
- β
remove useless ;await
- β
remove useless ;typeof
- β
remove useless ;template expressions
- β
remove useless ;for-of
- β
remove useless ;array.entries()
- β
remove useless ;debugger
- β
remove statement;iife
- β
remove ;process.exit
- β
remove nested blocks;
- β
remove call;console.log
- β
remove calls;empty block statements
- β
remove ;empty patterns
- β
remove ;strict mode
- β
remove directive from esm;constant conditions
- β
remove ;boolean
- β
remove from assertion;boolean
- β
remove from logical expressions;duplicates
- β
remove from TypeScript Union;unreachable code
- β
remove ;duplicate keys
- β
remove ;typescripts
- β
remove useless types;typescripts
- β
remove duplicate interface keys;test.only
- β
replace to test calls;test.skip
- β
replace to test calls;init
- β
reuse duplicate ;variable declarations
- β
split ;nested destructuring
- β
split ;assignment
- β
simplify ;ternary
- β
simplify ;logical expressions
- β
simplify ;strict mode
- β
if absent directive in commonjs add it;const
- β
convert to let (when needed to avoid TypeError);apply
- β
convert to spread;bitwise
- β
convert to logical operator;concat
- β
convert to flat;esm
- β
convert to commonjs (enabled for *.cjs);commonjs
- β
convert to esm (enabled for *.mjs);template
- β
convert with one expression to string;equal
- β
convert to strict equal;indexOf
- β
convert to includes;replace
- β
convert to replaceAll;assignment
- β
convert to arrow function;forEach
- β
convert to for...of;map
- β
convert to for...of;reduce
- β
convert to for...of;Math.sqrt()
- β
convert to Math.hypot();return await
- β
extract sequence expressions;
- β
extract object properties;
- β
add ;Promise.resolve
- β
remove useless ;Promise.reject
- β
convert to throw;reference
- β
declare before ;undefined variables
- β
declare ;imports
- β
declare first;as
- β
apply type assertions;utility types
- β
apply ;array.at
- β
apply ;filter(Boolean)
- β
apply ;if condition
- β
apply isArray;
- β
apply ;await import
- β
apply ;flatMap()
- β
apply comparison order;
- β
apply ;template literals
- β
apply ;imports
- β
merge duplicate ;functions
- β
merge duplicate ;
``
npm i putout -D
``
Usage: putout [options] [path]
Options:
-h, --help display this help and exit
-v, --version output version information and exit
-f, --format [formatter] use a specific output format, the default is: 'progress-bar' locally and 'dump' on CI
-s, --staged add staged files when in git repository
-i, --interactive set lint options using interactive menu
--fix apply fixes of errors to code
--fix-count [count = 10] count of fixes rounds
--rulesdir use additional rules from directory
--transform [replacer] apply Replacer, for example 'var __a = __b -> const __a = __b', read about Replacer https://git.io/JqcMn
--plugins [plugins] a comma-separated list of plugins to use
--enable [rule] enable the rule and save it to '.putout.json' walking up parent directories
--disable [rule] disable the rule and save it to '.putout.json' walking up parent directories
--enable-all enable all found rules and save them to '.putout.json' walking up parent directories
--disable-all disable all found rules (set baseline) and save them to '.putout.json' walking up parent directories
--match [pattern] read '.putout.json' and convert 'rules' to 'match' according to 'pattern'
--fresh generate a fresh cache
--no-config avoid reading '.putout.json'
--no-ci disable the CI detection
--no-cache disable the cache
--no-worker disable worker thread
To find errors:
``
putout lib test
To fix errors:
``
putout lib test --fix
By default πPutout uses all enabled by default plugins, anyways it can be run with a couple mentioned plugins (split with ","):
`sh`
putout lib --plugins remove-debugger,remove-unused-variables
πPutout supports next environment variables:
- PUTOUT_FILES - files that should be processed by putout, divided by ",";PUTOUT_CONFIG_FILE
- - path to πPutout config file;ESLINT_CONFIG_FILE
- - path to ESLint config file;NO_ESLINT
- - do not run ESLint after πPutout;NO_ESLINT_WARNINGS
- - do not show ESLint warnings;
`sh`
PUTOUT_FILES=lib,test putout --fix
To configure create .putout.json file and override any of default options.
When you need to match paths to rules you can use match section for this purpose in .putout.json:
`json`
{
"match": {
"server": {
"remove-process-exit": true
}
}
}
When you need to ignore some routes no metter what, you can use ignore section in .putout.json:
`json`
{
"ignore": ["test/fixture"]
}
πPutout supports two types of plugins, prefix with:
- β
@putout/plugin-;putout-plugin-
- β
;
To use your plugin createnpm package with keywords putout, putout-plugin and add it to .putout.json.
For example if you need to remove-something create πPutout plugin with name putout-plugin-remove-something and it to package.json:
`json`
{
"plugins": ["remove-something"]
}
πPutout supports codemodes in the similar to plugins way, just create a directory ~/.putout and put your plugins there. Here is example: convert-tape-to-supertape and this is examples of work.
All examples works both in ESM and CommonJS.
CommonJS:
`js`
const {putout} = require('putout');
ESM:
`js`
import {putout} from 'putout';
`js
import {putout} from 'putout';
const source =
const t = 'hello';
const m = t + '!';
console.log(t);;
putout(source, {
plugins: ['remove-unused-variables'],
});
// returns
const t = 'hello';
console.log(t);;`
`js
import {putoutAsync} from 'putout';
const source =
const t = 'hello';
const m = t + '!';
console.log(t);;
await putoutAsync(source, {
plugins: ['remove-unused-variables'],
});
// returns
const t = 'hello';
console.log(t);;``
MIT