Skip to content
 
 

Repository files navigation

ESLint Shareable Configs

This repository contains the standard ESLint shareable configuration for Bedrock projects.

It ships as flat config and targets ESLint 9+ (developed and tested against ESLint 10).

There is one entrypoint per runtime — Node.js, React, and Angular — plus a plain-JS root. All three runtime entrypoints share the same rules, so TypeScript that does not import a framework lints identically under all of them.

Choosing an entrypoint

Entrypoint For
@bdrk/eslint-config Plain JavaScript. Rules only — you supply the environment
@bdrk/eslint-config/node TypeScript on Node.js
@bdrk/eslint-config/react TypeScript + JSX in the browser
@bdrk/eslint-config/angular TypeScript in Angular

Install the package:

npm install --save-dev @bdrk/eslint-config

Each entrypoint exports an array of flat config objects. Spread it into your own config and add project-specific overrides afterwards.

Node.js:

// eslint.config.js
const bdrk = require('@bdrk/eslint-config/node');

module.exports = [
  ...bdrk,
  {
    // project-specific overrides
  },
];

/react and /angular are used the same way. Using ES modules? Import the default export instead:

// eslint.config.mjs
import bdrk from '@bdrk/eslint-config/react';

export default [
  ...bdrk,
  // project-specific overrides
];

Plain JavaScript uses the root entrypoint. It declares no globals, so add the ones your code actually runs with:

// eslint.config.js
const globals = require('globals');
const bdrk = require('@bdrk/eslint-config');

module.exports = [
  ...bdrk,
  {
    languageOptions: {
      globals: { ...globals.node },
    },
  },
];

Anything defined in this configuration can be overridden by adding a later config object with the rules you want to change.

What's included

  • Core: @eslint/js recommended rules plus Bedrock's conventions, formatting via @stylistic/eslint-plugin, import hygiene via eslint-plugin-import-x, and directive-comment hygiene via @eslint-community/eslint-plugin-eslint-comments.
  • TypeScript, in every runtime entrypoint: typescript-eslint recommended + type-checked rules and Bedrock's TypeScript conventions. Typed rules are scoped to .ts/.tsx/.mts/.cts, so plain .js files such as eslint.config.js are not subject to them.
  • Runtime layers: globals and parser options only — Node globals for /node, browser globals for /react and /angular, JSX parsing for .jsx/.tsx, and an import-x/first exemption for Angular's *.module.ts.

The TypeScript config uses typescript-eslint's projectService, so it auto-detects the nearest tsconfig.json — no parserOptions.project override required in most projects.

Framework plugins are not included

This package deliberately ships no framework plugins. Add them in your own config if you want them:

This keeps frontend plugins out of every Node service's dependency tree.

Contributing: the portability invariant

The point of this package is that code moves between runtimes without being rewritten. That rests on one rule:

All rules live in index.js or internal/typescript.js. A runtime layer may only set languageOptions (globals, parser options) and add files-scoped overrides for file shapes that exist solely in that framework. A runtime layer never sets a rule that another layer sets differently.

If a change appears to need a rule in node/, react/, or angular/, that is a signal the rule belongs in the core with a different value — not a signal to add it to the layer. The single sanctioned exception is Angular's **/*.module.ts override, which is safe because no other runtime has a file matching that pattern.

npm test enforces this: test/fixtures/portable/portable.ts is linted under all three runtime entrypoints and the three result sets must be identical, so a rule added to one layer fails the build. npm run lint lints this package with its own root config.

Migrating from the previous major

  1. @bdrk/eslint-config/typescript no longer exists. Use /node, /react, or /angular.
  2. The root entrypoint no longer supplies Node globals. Plain-JS projects add them as shown above; TypeScript projects should move to a runtime entrypoint.
  3. The I interface prefix is no longer enforced. Existing IFoo names still lint clean under PascalCase, so no rename is forced.

The rule changes only widen what is accepted — func-style, import-x/no-default-export, new-cap and the naming conventions all loosened — so the upgrade surface is essentially the entrypoint rename.

One thing to be aware of rather than surprised by: explicit-function-return-type applies to functions assigned to variables, so React components written as const Foo = () => … need a return-type annotation (: ReactElement). This is the existing Bedrock convention, unchanged by this release, and it applies identically in every runtime.

About

Standard ESLint shareable configuration for Bedrock projects.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages