npm.io
1.1.0 • Published 3d ago

@jabrown93/dev-config

Licence
MIT
Version
1.1.0
Deps
14
Size
22 kB
Vulns
0
Weekly
0

@jabrown93/dev-config

Shared JS/TS dev-tooling config for jabrown93 repos: TypeScript, ESLint, Prettier, commitlint, lint-staged, and semantic-release. One published package instead of six hand-copied config files per repo — bump this package's version and Renovate proposes the same bump everywhere it's used, the same way runtime dependency bumps already flow.

This is the npm-package analog of jabrown93/.github, which centralizes reusable GitHub Actions workflows the same way. That repo is deliberately unpublished (private: true, consumed via uses:); this one is a real published package because its configs are consumed at author/commit time via devDependency + extends, not by Actions.

Usage

Add the package:

npm install --save-dev @jabrown93/dev-config

TypeScript

Requires typescript 5.7+target/lib: ES2024 isn't recognized before that (declared as a peerDependencies floor; npm will warn on install if the consumer's typescript is older).

// tsconfig.json
{
  "extends": "@jabrown93/dev-config/tsconfig",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist"
  },
  "include": ["src"]
}

rootDir/outDir must stay in the consumer's own tsconfig.json, not the shared base: TypeScript resolves an extended config's relative paths against that config file's own location, so a rootDir/outDir baked into this package would resolve to paths inside node_modules/@jabrown93/dev-config/, not the consumer's own src/dist — breaking every consumer with a TS6059 "not under rootDir" error.

ESLint (flat config)
// eslint.config.mjs
import base from '@jabrown93/dev-config/eslint';

export default [...base, { ignores: ['**/dist'] }];

The only thing that's ever differed across the fleet is ignores — add repo-specific entries after the shared base.

Prettier
// package.json
{
  "prettier": "@jabrown93/dev-config/prettier"
}

Delete any local .prettierrc.json — Prettier uses one config source, not both.

commitlint
// commitlint.config.js
export default { extends: ['@jabrown93/dev-config/commitlint'] };
lint-staged
// .lintstagedrc.js
export { default } from '@jabrown93/dev-config/lint-staged';

Delete any local .lintstagedrc.json or an inline lint-staged key in package.json — only one lint-staged config source should exist per repo.

semantic-release
// .releaserc.json
{ "extends": "@jabrown93/dev-config/release" }

extends is a resolver string, not code — this works from a .releaserc.json even though the referenced module runs code at load time.

This config suppresses routine fix(deps) commits on ordinary pushes and promotes them into a single weekly patch release when the caller's workflow sets RELEASE_DEPS=true (see jabrown93/.github's README, "Weekly dependency releases"). A consumer's release.yml must add a schedule (and ideally workflow_dispatch) trigger for this to ever fire — without one, fix(deps) commits are suppressed forever, not just batched. See this repo's own .github/workflows/release.yml, or homebridge-smartrent's, for the trigger shape to copy.

What stays per-repo

No npm-extends mechanism exists for .prettierignore or .nvmrc — those stay hand-maintained per repo.

What's exported

Subpath Contents
@jabrown93/dev-config/tsconfig Shared compilerOptions (target/module/strict/etc.) — no rootDir/outDir/include/exclude, those must stay in the consumer's own tsconfig (see above)
@jabrown93/dev-config/eslint Flat-config array (parser, eslint:recommended + @typescript-eslint/recommended, the fleet's stylistic rules)
@jabrown93/dev-config/prettier The 5 shared Prettier options
@jabrown93/dev-config/commitlint @commitlint/config-conventional + 4 rule overrides
@jabrown93/dev-config/lint-staged eslint --fix on staged js/mjs/ts + prettier --write on staged js/mjs/ts/json/md/yml
@jabrown93/dev-config/release semantic-release config: branches main/next/beta/alpha, conventionalcommits preset, CHANGELOG trim, CycloneDX SBOM release asset, fix(deps) weekly roll-up

Dependency split

Tools whose bin a consumer invokes directly (eslint, prettier, typescript, husky, lint-staged, semantic-release, @commitlint/cli, plus each repo's own test runner) stay as direct devDependencies in the consumer. Packages this config resolves internally at runtime and a consumer never invokes directly (@typescript-eslint/*, @eslint/js, @eslint/eslintrc, @commitlint/config-conventional, every @semantic-release/* plugin, conventional-changelog-conventionalcommits) are dependencies of this package — they arrive in a consumer's tree via normal npm hoisting when this package installs, and a version bump here is the only place those need touching.

Versioning

Released automatically by semantic-release from Conventional Commits on main — see .releaserc.js (a relative re-export of release.js; this repo can't extends its own published package). Don't hand-edit package.json's version.

Keywords