Coding Standard
@modularityjs/coding-standard is the shared ESLint flat-config used by every package in this repo, exported in two variants so downstream apps can adopt the same TypeScript baseline without inheriting framework-specific rules they don't need.
Install
pnpm add -D @modularityjs/coding-standard eslintThe package depends on ESLint 10. It bundles typescript-eslint, @eslint/js, eslint-plugin-simple-import-sort, globals, and the in-house framework rules — no extra plugins to install.
The
@modularityjs/*scope publishes to a private registry. Ifpnpm addfails with 404 or 401, see Registry Access for the.npmrcsetup.
Pick a variant
| Factory | Adds framework rules | inversify blocked | Use case |
|---|---|---|---|
createBaseConfig | no | no | Downstream consumer apps; mixed codebases. |
createConfig | yes | yes | The default. Any package or app that wires up the framework. |
createFrameworkConfig | yes | yes | Framework-internal packages. Alias of createConfig — keeps intent explicit at the call site. |
createDriverConfig | yes | no | DI driver packages (di-inversify, di-awilix) that must import the underlying container. |
Consumer app (generic)
// eslint.config.mjs
import { createBaseConfig } from '@modularityjs/coding-standard';
export default createBaseConfig(import.meta.dirname);You get: typescript-eslint recommended, simple-import-sort with a slot for @modularityjs/* imports, sane TypeScript defaults (no-floating-promises, no-misused-promises, await-thenable, consistent-type-imports, no-unused-vars with underscore escape), eqeqeq, curly, and strict-boolean-expressions on src/**/*.ts (excluding tests). No framework-specific rules — your code can use forRoot, naming patterns like *Service, etc. without triggering the framework lints.
Framework consumer (recommended)
import { createConfig } from '@modularityjs/coding-standard';
export default createConfig(import.meta.dirname);Adds:
driver-service-naming— drivers export{Driver}{Domain}Service, not the inverse.forroot-returns-own-module— a module'sforRootreturns its ownModuleDefinition.pool-useclass-contract—{ provide, useClass }pairs match contract/driver types.module-name-matches-package—CacheModulelives in@modularityjs/cache.boundary-import— production source only imports from packages declared in the module'simports: [...].plugin-handler-return-type,before-plugin-args-shape,around-plugin-proceed-signature— AOP plugin signatures.hook-name-typo— catches near-misses likeonIntit,onReady→onRedy,onShutdown→onShutdwn, etc. (canonical names likeonReadyitself never trip the rule).- A
no-restricted-importsban oninversify(use@modularityjs/di).
DI driver
import { createDriverConfig } from '@modularityjs/coding-standard';
export default createDriverConfig(import.meta.dirname);Same as createConfig but lifts the inversify import restriction. Only @modularityjs/di-inversify and @modularityjs/di-awilix need this.
Layering project rules
Each factory returns a plain ESLint flat-config array. Concatenate to add project-specific rules:
// eslint.config.mjs
import { createBaseConfig } from '@modularityjs/coding-standard';
export default [
...createBaseConfig(import.meta.dirname),
{
files: ['src/**/*.ts'],
rules: {
// Tighten or override here.
'@typescript-eslint/explicit-function-return-type': 'error',
},
},
];Companion repo checks
The same package ships three repo-level scripts you can wire into any monorepo using the framework:
| Script | Purpose |
|---|---|
node node_modules/@modularityjs/coding-standard/check-boundaries.mjs | Verifies every cross-package import corresponds to a @Module({ imports: [...] }) entry. Static enforcement of the abstraction boundary. |
node node_modules/@modularityjs/coding-standard/check-dependencies.mjs | Ensures dependencies / peerDependencies / devDependencies match what production source and tests actually import. |
node node_modules/@modularityjs/coding-standard/check-manifest.mjs | Verifies every publishable package declares modularityjs.kind (and modularityjs.extends for drivers and extensions). |
The framework monorepo runs these via Turborepo (pnpm check-boundaries, pnpm check-dependencies, pnpm check-manifest). Drop the same turbo task definitions into your repo's turbo.json to gate CI on them.