eslint-config-love: a strict TypeScript shareable config with no formatting rules
A TypeScript ESLint config that loves you
At a glance
- What is it?
- An ESLint shareable configuration that turns on 264 rules across ESLint, typescript-eslint, eslint-comments, eslint-plugin-n and eslint-plugin-promise, deliberately leaves formatting to a separate tool, and versions every rule addition as a major release.
- Who is it for?
- Adopt eslint-config-love if you want a strict, opinionated TypeScript lint baseline and are willing to bump the major version every time the rule set grows. Do not adopt it if your team wants a config that stays stable across upgrades, because rule additions are major versions by policy, or if you expect formatting to come from ESLint, since that is explicitly out of scope.
- 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 last received commits 1 day ago.
- 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Five design decisions that define the config
eslint-config-love describes itself as an ESLint shareable configuration and then lists its principles, which are more useful than the rule count.
Safety at the cost of verbosity is the first, and it sets the tone. The config will ask you to write more code to satisfy a rule rather than relaxing the rule.
Convention over arbitrary choice is the second. Where the underlying tools allow several ways of doing something, the config picks one, so that the codebase is consistent rather than merely valid.
The third principle is the one that most affects daily work: no formatting rules, with a request to use a formatter instead. Formatting belongs to Prettier or whatever else you run, and keeping it out of ESLint means the two tools do not fight over the same lines.
The fourth is that the config contains no rules covered by strict TypeScript. If the TypeScript compiler already catches it, ESLint does not repeat it. That is a deliberate division of labour between the type checker and the linter.
The fifth is that there are no library, framework or syntactic extension specific rules. Nothing in the config knows about React, Jest, or a particular syntax proposal, which keeps it applicable to any TypeScript codebase rather than to a particular stack.
Together these make the config a policy document as much as a rule set, and they are the reasons a team either adopts it happily or fights it.
264 rules drawn from five plugin sources
The config turns on 264 rules, and the sources are listed.
ESLint itself provides the core rules. `@typescript-eslint` provides the TypeScript aware ones, which is the bulk of the value for a TypeScript codebase. `@eslint-community/eslint-comments` handles the rules about ESLint comments themselves, which matters because a config this strict will produce a lot of eslint-disable comments and you want those to be tidy. `eslint-plugin-n` covers Node.js specific conventions, and `eslint-plugin-promise` covers promise handling.
The package.json confirms the dependency set with matching version ranges: `@eslint-community/eslint-plugin-eslint-comments` at ^4.7.0, `@typescript-eslint/utils` and `typescript-eslint` both at ^8.71.0, `eslint-plugin-n` at ^18.0.1 and `eslint-plugin-promise` at ^7.3.0.
That the config depends on `typescript-eslint` rather than on individual plugin packages is a sign of where the ecosystem has moved. The umbrella package pulls in the parser and the plugin together and is the recommended install path in current documentation.
The rule count is worth keeping in mind when you adopt it. 264 rules is a large surface, and the documentation is candid about the consequence: some ad-hoc disabling of rules is expected, and the strict nature of the configuration means disabling will come up more frequently than with a lighter config.
The recommendation the documentation gives is to minimise the scope of any disabling, to prefer `eslint-disable-*` comments where possible, and otherwise to disable a rule for a subset of files using configuration.
Every rule addition is a major version, on purpose
The versioning policy is the most consequential thing about this config for anyone depending on it.
The rule is that any change which might require a user to make changes beyond upgrading the package is considered major. Rule additions are given as the obvious example. And the documentation goes further, saying it is expected that most version bumps will be major.
That is a rare and defensible choice. A shareable config that added a rule in a minor release would break builds, because a lint error is a build failure for most CI setups. Treating rule additions as breaking changes is the honest way to signal that an upgrade might require code changes, and it aligns the semver contract with what actually happens to a consumer.
The version numbers reflect that policy. The recent releases are v158.0.0 from 2026-10-02, v157.0.0 from 2026-09-11 and v156.0.0 from 2026-09-04, and the package version is 158.0.0. Two major releases in the space of a month is a lot of upgrades, and it means a team pinning this config will be pulling a new major version regularly.
The other side of that coin is that a user who wants a stable lint baseline has to pin an exact version and take on the work of upgrading deliberately. Given that a major bump here is a signal that new rules exist rather than that the package is broken, that is a reasonable trade for a team that wants the rules.
The package is published on npm under the name `eslint-config-love`, and the README carries badges for both the current name and the previous one, `eslint-config-standard-with-typescript`, since the rename.
The exported config turns on type aware linting
One setting in the exported configuration has real consequences for your setup, and it is called out separately in the documentation.
The config exported by the package sets `languageOptions.parserOptions.project = true`. That enables the type aware rules in typescript-eslint, the ones that need to know the type of a symbol rather than just its syntax. It is also what makes the value of a TypeScript specific ESLint config real, since rules about unsafe member access, unnecessary conditions or floating promises cannot work without type information.
The cost is that type aware linting needs a working TypeScript project to point at. The `project` option requires a tsconfig, and the documentation links to the typescript-eslint documentation for it, and also mentions there are some more `parserOptions` that you may care about.
The practical implication for anyone adopting this is that it is not a zero-configuration drop-in. If your project has a tsconfig that does not include every file you want linted, the type aware rules will fail to resolve types for those files, and the fix is in your tsconfig rather than in the config. That is the most common first-hour friction with this package.
The configuration itself is spread across `src/` in TypeScript and compiled to `lib/index.js`, which is the `main` entry in package.json. The package is marked as an ES module with `"type": "module"`.
Two config shapes, depending on your module system
The documentation gives example configuration files for both module systems, which is a small sign of care.
For ECMAScript Modules, the import is direct:
import love from 'eslint-config-love'
export default [
{
...love,
files: ['**/*.js', '**/*.ts'],
},
]For CommonJS, the import has to be dynamic because the package is an ES module, so the config is returned from an async function:
module.exports = (async function config() {
const { default: love } = await import('eslint-config-love')
return [
{
...love,
files: ['**/*.js', '**/*.ts'],
},
]
})()The `files` pattern in both examples is worth noting, because it is the mechanism for scoping the config. Since ESLint flat config applies rules to whatever matches, restricting the files pattern to JavaScript and TypeScript keeps the config off your build output and off any JavaScript in directories you did not mean to lint.
Running it is the ordinary ESLint invocation:
npx eslint .The examples are described as ESLint configuration files, and the documentation links to the ESLint guide on configuring it for anyone who needs more than the flat config model.
The repository is a well tooled TypeScript project
The build and release setup tells you how seriously the project treats its own quality, which matters for a config whose job is to police other people's code.
The scripts are the interesting part. `compile` runs tsc. `format/check` runs Prettier in check mode and `format/fix` runs it in write mode. `lint` runs ESLint on the project itself, which means the config lints its own repository. `unit` runs ava. The `test` script chains all of it with `run-s`: clean artifacts, check formatting, compile, run unit tests, then lint.
`prepublishOnly` runs `is-code-clean` and `compile`, and `is-code-clean` is a `git diff-index HEAD --quiet` check, so a publish cannot happen with uncommitted changes in the working tree. `clean-artifacts` uses `git clean lib -X --force` to remove the ignored build output.
The tooling around that is visible in the file list: `lefthook.yml` for git hooks, `commitlint.config.js` with conventional commits, `.releaserc.yml` for the release process, `shell.nix` for a reproducible development environment, `.prettierrc.yml` and `.prettierignore`, `.editorconfig`, and a CHANGELOG.md.
The project is developed primarily in remote mob programming format, and the README says to contact the author to apply for participation, with CONTRIBUTING.md as the other route in.
The licence is MIT, and the repository is not archived with the last push on 2026-10-19, so the config tracks current ESLint and typescript-eslint releases closely.
Editorial conclusion
Adopt eslint-config-love if you want a strict, opinionated TypeScript lint baseline and are willing to bump the major version every time the rule set grows. Do not adopt it if your team wants a config that stays stable across upgrades, because rule additions are major versions by policy, or if you expect formatting to come from ESLint, since that is explicitly out of scope. Verify first that the type aware rules work in your setup, since the exported config sets parserOptions.project = true and that requires a working TypeScript project reference.
Frequently asked questions
What is eslint-config-love?
It is an ESLint shareable configuration for TypeScript, described as a config that loves you. It enables 264 rules from ESLint, typescript-eslint, eslint-comments, eslint-plugin-n and eslint-plugin-promise.
Does eslint-config-love include formatting rules?
No. The configuration explicitly contains no formatting rules and asks you to use a formatter instead, on the grounds that formatting and linting should not fight over the same lines.
Why does eslint-config-love bump the major version so often?
Because any change requiring you to do more than upgrade the package is treated as major, and rule additions are the obvious case. The documentation says it is expected that most version bumps will be major, and the recent releases v156.0.0, v157.0.0 and v158.0.0 landed in September and October 2026.
Does eslint-config-love need a tsconfig file?
Yes, effectively. The exported config sets languageOptions.parserOptions.project = true, which enables the type aware rules, and those rules need a working TypeScript project reference to resolve types.
How do I use eslint-config-love in a CommonJS project?
Because the package is an ES module, the CommonJS example dynamically imports it inside an async function and returns the config array, spreading love into an object whose files pattern covers JavaScript and TypeScript files.
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/mightyiam-eslint-config-love)Was this useful?