@spendgraph/config
v0.15.0
Published
The Biome, TypeScript, Vitest and Cucumber configuration spendgraph holds itself to.
Maintainers
Readme
@spendgraph/config
The Biome, TypeScript, Vitest, Cucumber, PostCSS and CSS configuration spendgraph holds itself to. No build, no runtime, no dependencies — the files are the package.
biome/{base,next}.json
typescript/{base,library,next,tests}.json
vitest/{index,strict-throw}.mjs
cucumber/index.mjs
postcss/index.mjs
css/{theme,typeset}.css
shadcn/components.jsonnpm install -D @spendgraph/configTypeScript
{
"extends": "@spendgraph/config/typescript/library.json",
"compilerOptions": { "outDir": "dist" },
"include": ["src"],
"exclude": ["src/**/tests/**"]
}| | |
| --- | --- |
| tsconfig.base.json | the language settings |
| tsconfig.package.json | base + declaration, for a library that ships types |
| tsconfig.next.json | a Next.js app — the DOM, JSX and the Next plugin |
| tsconfig.tests.json | an overlay, listed second so your own config comes first |
{ "extends": ["./tsconfig.json", "@spendgraph/config/typescript/tests.json"] }TypeScript takes an array and the later entry wins, so the overlay turns the emit off and adds the test globals over whatever you already had.
Nothing path-valued is in either, and nothing path-valued may be added. A
relative path in an extended config resolves against the file it is written in,
not the one extending it — an outDir of "dist" here would send every
consumer's build into node_modules/@spendgraph/config/dist. outDir,
rootDir, include, exclude, files, paths and typeRoots stay with
whoever extends. tests/repo/shared-config.test.ts enforces it.
Biome
{ "extends": ["@spendgraph/config/biome/base.json"] }Rules, formatter and import sorting. Biome's linter starts from preset: "none"
here, so every rule in it was chosen.
It is biome.base.json rather than biome.json on purpose: Biome discovers any
biome.json in the tree and treats it as a competing root configuration, which
fails the run inside a monorepo.
overrides are deliberately absent. Inherited overrides always sort before
your own, and the last match wins — so a shared override would quietly outrank
the relaxations you write for your own test folders. Overrides belong to the
config that owns their order.
Cucumber
import { cucumber } from "@spendgraph/config/cucumber";
export default cucumber(); // or cucumber({ format: ["progress"] })Features in features/, steps in features/**/*.steps.mts, support loaded
first so the World and any parameter types register before the steps that use
them. Run it with NODE_OPTIONS="--import tsx" — tsx/esm alone does not
register the CJS hook, and path aliases inside the modules under test then fail
to resolve.
Vitest
import { packageTests, appTests } from "@spendgraph/config/vitest";
export default defineConfig(packageTests()); // tests beside the source
export default defineConfig(appTests(import.meta.url)); // an app with an `@/` aliasappTests takes import.meta.url because the alias must resolve against the
consumer's root rather than this file's.
Both load strict-throw.mjs first. Without it, toThrow and toThrowError
with a pattern, a string or no argument pass when the code throws or rejects
with undefined or null, so a test written for an error path stays green
when that path throws nothing. A config that builds its own test adds
strictThrow from @spendgraph/config/vitest to setupFiles.
PostCSS
Next demands postcss.config.mjs at the root by name, so keep the file and
re-export:
export { default } from "@spendgraph/config/postcss";CSS
@import "tailwindcss";
@import "@spendgraph/config/css/theme.css";
@import "@spendgraph/config/css/typeset.css";theme.css is the design tokens and the dark variant; typeset.css is the
prose styles. @import "tailwindcss" stays in your own entry, because Tailwind
scans the importing project for the classes it must emit.
shadcn
shadcn/components.json. The CLI has no extends and reads the file from the
project root by name, so the root entry is a symlink into this package:
ln -s packages/config/shadcn/components.json components.jsonThe paths inside it — app/globals.css, @/components, @/lib/utils — are the
conventional Next + shadcn layout, which is what makes it shareable at all. A
project laid out differently should copy it and edit, not link it.
