Use as-is
My defaults suit you. One line and you are done.
// presetter.config.tsexport { default } from '@presetter/preset-esm';Configuration clarity for serious TypeScript teams
Describe your toolchain once in presetter.config.ts. Presetter installs declared packages and scripts, then generates the ESLint, Vitest and TypeScript config each repo expects, and keeps every repo in step when the preset moves.
One source of truth for every package
import { preset } from 'presetter';import essentials from '@presetter/preset-essentials';import react from '@presetter/preset-react';import strict from '@presetter/preset-strict'; export default preset('app', { extends: [essentials, react, strict],});The problem
Every repo starts clean. Then the same eslint, vitest, typescript, build, and lifecycle settings fork in small ways across apps, packages, services, and CLIs.
90-second explainer
Compose presets in one small file, generate the configs your tools expect, override a value in plain sight, and update by bumping the preset and running bootstrap again.
Opinionated by design
They encode how I build TypeScript projects: ESM first, strict linting, full coverage gates, Husky hooks. That fits my work. It may not fit yours, and Presetter is built for that.
My defaults suit you. One line and you are done.
// presetter.config.tsexport { default } from '@presetter/preset-esm';Keep the baseline, change the few values you disagree with, in plain sight.
export default preset('my-project', { extends: [esm], override: { variables: { source: 'source' }, assets: { '.gitignore': null }, },});Encode your team’s opinions once and share them across every repo you own.
export default preset('@acme/preset', { extends: [esm], scripts: { test: 'vitest' },});Managed scripts
Each script becomes a one-liner that calls run. Presetter looks the task up in your preset stack, expands the tasks it calls, and forwards anything after --. Update the preset and every repo picks up the new build, test, and release steps.
preset-esm replaces build:typescript from preset-essentials. Every other step is inherited as-is.
A script you write in package.json beats the preset version of the same name. Add --template to run the preset one anyway.
Patterns select tasks: * matches one level of subtasks, ** matches any depth.
Each preset adds its bin path to PATH, so eslint or vitest resolve without being direct dependencies.
A preset is the same preset() call you already write in presetter.config.ts, published as a package. Extend an official preset or start from nothing, add your opinions, and every repo that extends it stays in step.
import { preset } from 'presetter';import esm from '@presetter/preset-esm'; // your team's opinions, versioned in one placeexport default preset('@acme/preset', { extends: [esm], variables: { source: 'src', output: 'dist' }, setup: { scripts: { build: 'run build', test: 'run test --' } }, assets: { 'tsconfig.json': { compilerOptions: { target: 'ES2024' }, }, },});Interactive explorer
Pick a stack, then run the command in a project with a package.json. use installs its packages and scripts, writes the config, and bootstraps your tools. Your project’s package manager is detected; if none is found, you’ll be asked to choose.
import preset0 from '@presetter/preset-esm';import preset1 from '@presetter/preset-strict'; import { preset } from 'presetter'; import { name } from './package.json' with { type: 'json' }; export default preset(name, { extends: [preset0, preset1],});