tslint-to-eslint-config maps a TSLint setup onto ESLint, with a fallback for rules that have no equivalent
Converts your TSLint configuration to the closest possible ESLint equivalent. 🚀
At a glance
- What is it?
- A one-shot command that reads your TSLint, TypeScript and package configuration and writes an ESLint configuration, delegating unmatched rules to eslint-plugin-tslint.
- Who is it for?
- Use tslint-to-eslint-config when a project still carries a tslint.json and wants a starting ESLint configuration in a single command instead of a hand-written rewrite. Skip it for Angular projects, where angular-eslint coordinates the migration instead, and treat its output as a draft rather than a finished config, since rules without an ESLint equivalent are only wrapped by eslint-plugin-tslint and still need manual decisions.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The mapping is rule by rule, and the leftovers go to eslint-plugin-tslint
tslint-to-eslint-config solves a narrow, annoying problem: a project that lints with TSLint and needs to move to ESLint without losing the rules it already relies on. The command reads whatever linter, TypeScript and package configuration files it finds, then creates an ESLint configuration based on them.
The interesting part is the rule mapping, and the documentation is specific about the two cases. For any TSLint rule that has a corresponding ESLint equivalent, the equivalent is what lands in the new configuration. For TSLint rules with no ESLint equivalent, the tool does not drop them. It wraps them with eslint-plugin-tslint, which exists to keep TSLint rules running under ESLint.
That fallback is the reason the tool can honestly describe itself as producing the closest reasonable ESLint equivalent rather than a lossy approximation. It also means the generated file is a staging point, not a destination. Rules that survive only through the wrapper are still TSLint rules, and the project is paying to run two linters at once until somebody decides what each one should become.
The audience is teams with an existing TSLint investment and a deadline. A team that never used TSLint has nothing to convert and should configure ESLint directly.
Running the conversion is one command and the output lands in .eslintrc.js
The documented entry point uses npx, so no global install is required.
npx tslint-to-eslint-configThe default output path is .eslintrc.js, and the default inputs are the files the tool expects to find in the project root: tslint.json for the TSLint configuration, tsconfig.json for the TypeScript compiler options, and package.json for the dependency list. The generated file is written in the format implied by the extension of the output path, so a .js path produces a module.exports style JavaScript file and anything else produces JSON.
The tool reads the TSLint configuration by piping it into TSLint's own --print-config command, which is how it gets the resolved list of rules to enable rather than guessing at the raw file. The TypeScript and package inputs exist for a different reason: they inform the env settings in the generated ESLint configuration, so the parser options and globals match the project the tool just read.
Two runtime requirements are stated: Node 14 and later on an LTS line, and TSLint 5.18 or later. The package manifest agrees on the Node side, with an engines field requiring node >=14.0.0. TSLint is not a peer dependency here; the manifest lists tslint 6.1.3 among the runtime dependencies, along with typescript 4.9.5, commander, chalk, glob, minimatch, lodash and json5.
The --comments pass rewrites tslint:disable directives inside your source
Converting the configuration file is only half the job, because a TSLint codebase also carries inline directives in its source files. A file that silences a rule with a comment will still carry that comment after the config is converted, and ESLint will not understand it.
The comments flag handles this. It converts TSLint rule flags into ESLint inline comments, so a directive written as a tslint:disable for a named rule becomes the eslint-disable equivalent for the ESLint rule of that name.
npx tslint-to-eslint-config --commentsWithout arguments, the flag respects the exclude, files and include settings in your TypeScript configuration, which is the sensible default because it uses the same file set the compiler uses. You can override that in two ways. A single argument ending in .json is treated as a TypeScript configuration file describing which files to convert.
npx tslint-to-eslint-config --comments tsconfig.jsonAny other arguments are treated as glob paths for the files to convert, so you can point the flag at a directory pattern of TypeScript sources instead of relying on the compiler's own file list.
This is the flag people forget. A conversion that leaves stale tslint:disable comments behind produces a file that lints differently than before, and the difference is easy to misread as a rule mapping error rather than a missed comment.
Output path, editor settings and existing ESLint config are all separate flags
The remaining flags control where output goes and what else gets read. The config flag sets the path to print the generated ESLint configuration file to, and its default is .eslintrc.js.
npx tslint-to-eslint-config --config .eslintrc.jsonThe editor flag points at an editor configuration file whose TSLint settings get converted to their ESLint equivalents. Its default is .vscode/settings.json, and the documentation describes it as handling VS Code style editor settings for TSLint.
npx tslint-to-eslint-config --editor ./path/to/.vscode/settings.jsonThe eslint flag names an ESLint configuration file to read settings from, defaulting to the value of the config flag. Anything imported from that file is included in the generated configuration, which is how a project keeps a shared base config in place while the conversion writes the project specific layer.
npx tslint-to-eslint-config --eslint ./path/to/eslintrc.jsThe package flag points at the package.json whose dependencies inform the env settings, defaulting to package.json, and the typescript flag points at the tsconfig.json whose compiler options inform the same settings.
npx tslint-to-eslint-config --typescript ./path/to/tsconfig.jsonOne subtlety worth internalising: the eslint flag defaults to the value of the config flag. If you ask for a non-default output path and do not pass --eslint, the tool will try to read settings from the file it is about to write.
Prettier changes the generated file, and without the flag the tool argues for it
The prettier flag adds eslint-config-prettier to the list of ESLint plugins in the generated configuration, and its default is false.
npx tslint-to-eslint-config --prettierThe project recommends Prettier for code formatting and points at its own FAQ document for the reasoning. What matters for adoption is the behaviour when the flag is left off, which the documentation describes precisely. If the output configuration does not enable any formatting rules, the generated file extends from eslint-config-prettier anyway. If it does enable formatting rules, the tool prints a message suggesting you rerun with --prettier.
In other words, the tool tries to reach the same end state either way, but it only adds the plugin to the list when you ask, and it only does so silently when there is nothing to conflict with. That is a reasonable default, since Prettier and ESLint formatting rules can disagree, and the generated configuration is otherwise allowed to keep whatever formatting rules the TSLint side implied.
The FAQ document is also where the project says to start. The documentation strongly advises reading docs/FAQs.md before planning a conversion, and it links a specific section on whether to use Prettier. For a tool that rewrites your linting configuration, reading the FAQ first is the cheapest step available.
Angular projects are told to use angular-eslint instead
The documentation carries one explicit warning, and it is about a whole framework rather than a flag. It says that if you are coming from Angular, you should use angular-eslint instead, to coordinate around this tool and others.
The reason is structural rather than technical. An Angular workspace does not lint with a standalone TSLint configuration; it lints through the Angular CLI, and its templates, its own rules and the surrounding tooling have to move together. A tool that reads a tslint.json and writes an .eslintrc.js does not know about any of that. Running the conversion inside such a workspace would produce a file that no part of the build reads.
This is the clearest case of the tool being the wrong choice, and it is worth reading as a category rather than a single case. Any project whose linting configuration is not a standalone file that a command line tool can read and replace is out of scope. The tool's value comes entirely from being a mechanical reader and writer of four file types, and it stops being useful the moment the configuration lives somewhere else.
For everyone else, the output remains a draft. The generated file reflects what TSLint was doing, not what the team wants ESLint to do, and the wrapped rules carried by eslint-plugin-tslint still need decisions.
The Node API exposes the same conversion as a single await call
The tool is not limited to the command line. The documentation describes a Node API reachable through the package's exported functions, with details in docs/API.
import { convertLintConfig } from "tslint-to-eslint-config";
const result = await convertLintConfig();The exported main entry point of the package points at ./src/index.js, and the binary is declared in the manifest under a bin entry named tslint-to-eslint-config, which is what makes npx work. The API matters for one specific use case: scripting the conversion as part of a scripted setup or a migration commit, where you want the result object rather than a file written to disk.
The repository layout shows a project with real engineering discipline behind it. The source lives in src/, the compiled entry point in bin/, the documentation in docs/, and the tests are driven by jest with a jest.config.cjs at the root. Formatting is handled by Prettier with a .prettierrc and .prettierignore, lint-staged runs prettier on staged files, husky manages the git hooks, and dependabot.yml and renovate.json sit side by side for dependency updates. The TypeScript configuration is split into tsconfig.base.json, tsconfig.source.json, tsconfig.test.json and tsconfig.eslint.json, which tells you the build has separate concerns rather than one catch-all file.
All of that engineering serves a tool whose own runtime job is a single conversion.
MIT licensed, still receiving pushes, but releases are irregular
The project is MIT licensed, with the licence text in LICENSE.md at the repository root, and the manifest declares the same licence. MIT is permissive and carries no requirement to redistribute changes, so a company can use the tool internally and modify it without a separate agreement. As always, that is a reading of the licence text rather than legal advice.
On maintenance, the repository is not archived and the last push was on 2026-10-16. The release history is less regular than the commit activity suggests: v2.16.0 was published on 2025-12-20, v2.15.0 on 2025-11-04, and before that v2.14.0 on 2023-02-21, whose release note mentions ordered-imports. A gap of nearly three years between v2.14.0 and v2.15.0 is a reminder that a tool can keep receiving commits while its published version stays where it is, so pinning to the newest tag is not the same as running the newest code.
The upgrade cost of using the tool is close to zero once the conversion is done. It is a development-time utility with no runtime footprint in your application, and nothing in your bundle depends on it. The cost that remains is the one the tool cannot do for you, which is deciding what to do with the rules that eslint-plugin-tslint is holding in place.
Editorial conclusion
Use tslint-to-eslint-config when a project still carries a tslint.json and wants a starting ESLint configuration in a single command instead of a hand-written rewrite. Skip it for Angular projects, where angular-eslint coordinates the migration instead, and treat its output as a draft rather than a finished config, since rules without an ESLint equivalent are only wrapped by eslint-plugin-tslint and still need manual decisions. Verify first that the generated file names the dependencies your project actually has, that the `--comments` pass covered your inline tslint:disable comments, and that your Node and TSLint versions meet the stated requirement of Node 14 or later and TSLint 5.18 or later.
Frequently asked questions
How do I convert my TSLint config to ESLint with tslint-to-eslint-config?
Run npx tslint-to-eslint-config in the project root. The command reads your TSLint, TypeScript and package configuration files and writes an ESLint configuration, by default to .eslintrc.js.
What happens to TSLint rules that have no ESLint equivalent?
They are not dropped. The tool wraps them with eslint-plugin-tslint, so they keep working under ESLint, which means the generated configuration still carries TSLint behavior until you replace those rules by hand.
How do I convert my inline tslint:disable comments?
Run npx tslint-to-eslint-config --comments. With no arguments it respects the exclude, files and include settings in your TypeScript configuration, and you can pass a .json path to a tsconfig file or a glob path for TypeScript sources.
Can I use tslint-to-eslint-config in an Angular workspace?
The documentation advises against it and points Angular users to angular-eslint instead, because an Angular workspace lints through the Angular CLI and the surrounding tooling has to be coordinated separately.
What are the requirements for running tslint-to-eslint-config?
The documentation states Node 14 or later on an LTS line and TSLint 5.18 or later. The package manifest also declares an engines field requiring node >=14.0.0.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/typescript-eslint-tslint-to-eslint-config)