@devbie/style-guide
Single source of truth for code style across the devbie ecosystem
(newbie / fewbie / apits). See ADR-010 in worldzhy/devbie.
Exports
| Entry | Contents |
|---|---|
@devbie/style-guide/prettier | Canonical prettier config (all repos) |
@devbie/style-guide/eslint/base | Baseline eslint flat config for Node TypeScript |
@devbie/style-guide/eslint/nest | Nest layer (Nest-specific rules, type-aware) |
@devbie/style-guide/eslint/next | Next.js layer (canonical Next.js rules) |
nest and next are layers, not standalone standards: every consumer
composes [...base, ...nest] or [...base, ...next]. The baseline carries
the shared language-level rules and prettier; a layer adds only its
framework's rules. base alone covers CLIs, code generators, registries, and
SDKs.
Coverage: which entry each repo uses
| Repo | Composition |
|---|---|
| devbie monorepo root | base + nest scoped to packages/newbie |
| newbie-starter | base + nest |
| fewbie-starter | base + next |
| newbie-modules | base + nest |
Two structural facts drive this table:
newbie-modulesis a pure source registry — module sources are copied into a consumer rather than built in place — but those sources are Nest code, so it composes[...base, ...nest]withinjectable-should-be-providedscoped off: there is no host module graph in the registry for the rule to resolve providers against, and the host keeps the rule enabled where that graph exists.- The devbie monorepo root lints heterogeneous packages in one config: only
packages/newbieis Nest framework code, while the CLIs, the generator and the SDKs are plain Node. ESLint flat config does not readpackage.jsonand nestedeslint.config.mjsfiles are not inherited, so per-package differentiation must be expressed in the root config withfilesscoping — never with per-package config files orpackage.jsonentry fields.
next (and nest) must be loaded where the framework's packages are
installed: eslint-config-next requires next at load time (declared as an
optional peer, so base/nest consumers are never forced to install Next.js),
and the Nest layer requires a TypeScript project for its four type-aware
rules. The Nest plugin's own peer declarations carry the rest — nothing
imports class-validator at lint runtime.
Usage
prettier
Delete any local .prettierrc and reference the shared config in
package.json:
{
"prettier": "@devbie/style-guide/prettier"
}
.prettierignore stays repo-local: it lists repo-specific build artifacts,
not style decisions.
eslint (flat config)
eslint.config.mjs in the consumer repo:
import base from "@devbie/style-guide/eslint/base";
// Nest apps: import nest from "@devbie/style-guide/eslint/nest";
// Next.js apps: import next from "@devbie/style-guide/eslint/next";
export default [
...base,
// ...nest or ...next, then repo-specific rules and ignores.
];
Consumers need eslint (^9 or ^10), prettier (^3.9.9) and typescript
installed as their own dev dependencies (declared as peers of this package).
Version policy
All devbie packages stay on the 1.x line until the ecosystem launches; breaking style changes bump minor, not major. Dependency major upgrades of prettier/eslint follow the ecosystem-wide major-freeze policy: not by default, only as a deliberate milestone.
Changelog
- 1.4.1 — the optional
nextpeer widens to^16.0.0. 1.4.0 declared^16.4.2(mirroring the dev dependency used by this package's own test suite), but npm enforces optional-peer ranges against installed copies, so consumers on Next.js 16.2 failed to install with ERESOLVE. The peer now states the actual contract: any Next.js 16. - 1.4.0 — the three eslint entries ship type declarations (exports map
typesalongsidedefault), and thenextlayer switches offimport/no-anonymous-default-exportforeslint.config.*files so consumers can use the idiomaticexport default [...base, ...next].nextis declared as an optional peer. - 1.3.1 — the internal
coreentry is inlined intobaseand removed. Nothing imported it directly (basewas its only consumer), and keeping two files for one entry set made the loading order harder to read:nestandnexteach also end onprettierConfig, so there is no shared tail to factor out. - 1.3.0 — new
nestlayer backed by@darraghor/eslint-plugin-nestjs-typed(recommended flat config, four type-aware rules), andnextreshaped into a layer. Consumers now compose[...base, ...nest]/[...base, ...next]; this also lets the devbie monorepo scope the Nest layer topackages/newbieviafilesinstead of giving a Nest framework standard to its CLIs. - 1.2.0 —
backendrenamed tobaseandfrontendremoved. After apits and fewbie-cli joined the newbie monorepo (ADR-012/ADR-015),frontendhad no consumer left, andbackendno longer described its consumers (CLIs, code generators, registries — none of them backends). The pair is now named for what it is:base(the default) andnext(the Next.js specialization). The react/react-hooks/jsx-a11y plugin dependencies are dropped;nextgets those layers fromeslint-config-next. - 1.1.3 —
frontendpins the React version for rule evaluation (19.0) instead of detecting it: fewbie lints React template sources without areactpackage installed, where detection only emits a warning. - 1.1.2 — fix:
nextextendscoreplus the canonical Next rule set (eslint-config-nextalready bundles React/react-hooks/jsx-a11y, so spreadingfrontendon top redefinedjsx-a11yand flat config rejected it). ThefrontendReact layer is now scoped to JSX/TSX files, so Node code in frontend repos is not evaluated against React rules while React template sources are. - 1.1.1 — fix:
frontenduses the flat variant of eslint-plugin-react-hooks (configs.flat["recommended-latest"]); 1.1.0 shipped the legacy shape and failed to load under flat config. - 1.1.0 — entries renamed to
backend/frontendand layered:coreis internal,frontendis framework-independent (React rules only),nextadds the canonical Next.js rule set.nestwas replaced bybackend. - 1.0.0 — initial release (
prettier,eslint/nest,eslint/next).