@paciolan/code-standards
v1.0.0
Published
Paciolan shared code standards: ESLint flat configs, Prettier config, and TypeScript config presets
Maintainers
Readme
@paciolan/code-standards
Paciolan's shared code standards in one package, consumed through three subpath exports:
| Subpath | What it is |
| --- | --- |
| @paciolan/code-standards/eslint/* | ESLint flat configs (ESLint 9 and 10) plus the pac custom-rules plugin |
| @paciolan/code-standards/prettier | Org-wide Prettier settings |
| @paciolan/code-standards/tsconfig/* | TypeScript config presets (roles × layers) |
One dependency, one version bump per repo.
npm install --save-dev @paciolan/code-standards eslint prettier typescriptPeer requirements: eslint ^9 or ^10, prettier ^3, typescript >=5 (only
if you use the TypeScript-aware configs or tsconfig presets).
ESLint
Pick the entry matching the repo, re-export it from eslint.config.mjs, and
delete the repo's hand-rolled rules. Entries are cumulative — each one
includes everything below it in the table:
| Entry | Adds | Use for |
| --- | --- | --- |
| eslint/base | eslint recommended, Prettier-as-error | plain JS utilities |
| eslint/typescript | typescript-eslint recommended, unused-import auto-removal, _-prefix conventions | headless TS libraries |
| eslint/react | browser globals, react-hooks, import sorting | React components/libs |
| eslint/react-query | @tanstack/query correctness rules | operator remote components |
| eslint/node | node globals, security + n plugins, type-aware promise rules, no-console | node services (layered on typescript) |
| eslint/nest | Nest-specific guards | NestJS services |
| eslint/lambda | pac/no-direct-aws-sdk-v3-instance | AWS lambdas |
// eslint.config.mjs — operator remote component
import reactQuery from "@paciolan/code-standards/eslint/react-query";
export default reactQuery;// eslint.config.mjs — node service / nest / lambda, adding repo-local tweaks
import node from "@paciolan/code-standards/eslint/node";
export default [
...node,
{ rules: { "@typescript-eslint/no-explicit-any": "off" } }
];Notes:
- Type-aware rules (
no-floating-promises,no-misused-promises,return-awaitin the node family) resolve yourtsconfig.jsonvia typescript-eslint's project service. Run ESLint from the repo root; if you don't, add{ languageOptions: { parserOptions: { tsconfigRootDir: import.meta.dirname } } }. - react-hooks is pinned to the classic pair (
rules-of-hookserror,exhaustive-depswarn). The plugin's v6+recommendedpreset bundles the React Compiler rule set; adopting those is a deliberate future change to this package. - Unused code: unused imports are removed by
--fix; unused vars/args/catch params warn unless named with a leading_. - Repos that register additional plugins (e.g.
eslint-plugin-react) do so in their own config entry appended after the shared array.
Custom rules (pac/ plugin)
Standalone usage:
import pacPlugin from "@paciolan/code-standards/eslint/plugin";
export default [
{
plugins: { pac: pacPlugin },
rules: { "pac/no-direct-aws-sdk-v3-instance": "error" }
}
];pac/no-direct-aws-sdk-v3-instance
Disallows binding *Client names from @aws-sdk/client-* packages (both
import and require destructuring), so lambdas and services reuse the
shared singleton clients instead of constructing their own per call site.
Enabled by the lambda entry; test files are exempt. Disable it inline in
the one module that owns the singletons:
// eslint-disable-next-line pac/no-direct-aws-sdk-v3-instance
import { S3Client } from "@aws-sdk/client-s3";Prettier
Point the prettier key of package.json at the shared config and delete
.prettierrc:
{
"prettier": "@paciolan/code-standards/prettier"
}Settings: tabWidth: 2, trailingComma: "none" (matches the operator fleet
and existing code; everything else is Prettier defaults). The ESLint configs
enforce the same settings through prettier/prettier, so editors and CI
can't drift.
TypeScript
Extend one role, then stack layers as needed (later entries win):
| Role | For |
| --- | --- |
| tsconfig/react-lib | browser React components/libs (typecheck-only; the bundler emits) |
| tsconfig/node-service | node services compiled with tsc (NodeNext, no DOM lib) |
| tsconfig/nest | NestJS services (CommonJS + legacy decorators) |
| tsconfig/lambda | AWS lambdas (node-service alias, stable extension point) |
| Layer | Effect |
| --- | --- |
| tsconfig/strict | extra strictness: noUncheckedIndexedAccess, noImplicitReturns, noImplicitOverride |
| tsconfig/jest | types: ["node", "jest"] |
| tsconfig/vitest | types: ["node", "vitest/globals"] |
| tsconfig/esmodule | NodeNext module semantics (flip a nest/service to ESM) |
| tsconfig/commonjs | CommonJS module semantics |
// tsconfig.json — React component with vitest
{
"extends": [
"@paciolan/code-standards/tsconfig/react-lib",
"@paciolan/code-standards/tsconfig/vitest"
],
"include": ["src"]
}// tsconfig.json — ESM NestJS service
{
"extends": [
"@paciolan/code-standards/tsconfig/nest",
"@paciolan/code-standards/tsconfig/esmodule"
],
"compilerOptions": { "baseUrl": "src/", "outDir": "dist/" },
"include": ["./"]
}Every role is strict: true. Heads-up: types replaces rather than
merges across extends — a repo needing extra ambient types (e.g.
@testing-library/jest-dom) sets the full types array itself.
Versioning and publishing
Releases are cut by semantic-release from conventional commits on master
(fix: → patch, feat: → minor). A rule/config change that will produce new
errors in consuming repos is a breaking change — release it as a major.
Attribution
The tsconfig preset structure (roles extended by layers) is adapted from the MIT-licensed @code-style/typescript-configs by Louis Orleans.
