Shared configuration packages for btravstack
repositories. Each repo used to hand-copy a near-identical tools/tsconfig,
tools/typedoc, oxlint, oxfmt, commitlint, and lefthook setup; this monorepo
publishes them once, under the same @btravstack npm scope as
@btravstack/theme.
Every package is consumed via native config inheritance (extends), not a
build step — they ship static config files, so there is nothing to compile.
| Package | What it shares | Inheritance |
|---|---|---|
@btravstack/tsconfig |
Strict TS base (strict + exactOptionalPropertyTypes + noUncheckedIndexedAccess + noPropertyAccessFromIndexSignature …, NodeNext, ES2022) |
tsconfig.json extends |
@btravstack/typedoc |
TypeDoc markdown base (markdown plugin, table formats) | typedoc.json extends |
@btravstack/oxlint |
oxlint rules (no-explicit-any, type-only definitions) |
.oxlintrc.json extends |
@btravstack/oxfmt |
oxfmt settings | copy-template — oxfmt has no extends |
@btravstack/commitlint |
Conventional-commits preset | commitlint.config.js extends |
@btravstack/lefthook |
pre-commit / commit-msg hooks | lefthook.yml extends |
Install the packages you need (they belong in devDependencies), then wire each
one up:
tsconfig — in a package's tsconfig.json:
typedoc — in typedoc.json (bring your own typedoc-plugin-markdown):
{ "extends": "@btravstack/typedoc/base.json", "entryPoints": ["src/index.ts"] }oxlint — oxlint resolves extends by file path, so point at the file in
node_modules (the same style already used for $schema):
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"extends": ["./node_modules/@btravstack/oxlint/base.json"],
}oxfmt — oxfmt has no extends; copy @btravstack/oxfmt/base.json into
your .oxfmtrc.json and add repo-specific ignorePatterns.
commitlint — in commitlint.config.js:
export default { extends: ["@btravstack/commitlint"] };lefthook — in lefthook.yml:
extends:
- node_modules/@btravstack/lefthook/lefthook.ymlFirst-party packages skip the supply-chain maturity delay: add
@btravstack/*tominimumReleaseAgeExcludein the consumer'spnpm-workspace.yaml, next to@btravstack/theme.
pnpm install
pnpm test # validate every shipped config parses/loads
pnpm lint
pnpm formatReleases flow through changesets and
npm Trusted Publishing (OIDC — no NPM_TOKEN). Add a changeset with
pnpm changeset; merging the generated "release packages" PR publishes.
Two reusable workflows live under .github/workflows so
consumer repos stop hand-copying CI/release YAML:
ci-reusable.yml— one job that runs the whole gate after a single install (format → lint → typecheck → knip → test → build → audit → optional changeset check). Inputs:knip,changeset,security-audit,test-command,node-version-file.release-reusable.yml— changesets + npm Trusted Publishing. Takes aRELEASE_PATsecret.
Consume them from thin caller workflows:
# .github/workflows/ci.yml
name: CI
on:
push: { branches: [main] }
pull_request: { branches: [main] }
jobs:
ci:
uses: btravstack/config/.github/workflows/ci-reusable.yml@main
with:
changeset: true # contract repos that enforce changesets# .github/workflows/release.yml
name: Release
on:
workflow_run: { workflows: ["CI"], types: [completed], branches: [main] }
jobs:
release:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: btravstack/config/.github/workflows/release-reusable.yml@main
secrets:
RELEASE_PAT: ${{ secrets.RELEASE_PAT }}Repo-specific jobs (bundle-size, integration tests, docs deploy) stay in the
caller's own workflow file alongside the uses: call.
MIT © Benoit Travers
{ "extends": "@btravstack/tsconfig/base.json" }