Opinionated TypeScript project template with strict tooling pre-configured.
| Tool | Purpose |
|---|---|
| TypeScript | Type checking (@tsconfig/strictest) |
| ESLint | Linting (strict type-checked + custom rules) |
| dprint | Code formatting |
| cspell | Spell checking |
| markdownlint | Markdown linting |
| commitlint | Conventional commit messages |
| husky | Git hooks |
| nano-staged | Pre-commit staged file checks |
| commitizen | Commit message wizard |
All scripts are written in TypeScript and executed via jiti.
npx degit mnaoumov/typescript-template my-project
cd my-project
npm install| Command | Description |
|---|---|
npm run build:compile |
TypeScript type check |
npm run lint |
ESLint check |
npm run lint:fix |
ESLint check + auto-fix |
npm run format |
Format code (dprint) |
npm run format:check |
Check formatting |
npm run spellcheck |
Spell check (cspell) |
npm run lint:md |
Markdown lint |
npm run lint:md:fix |
Markdown lint + auto-fix |
npm run commit |
Commitizen commit wizard |
├── src/ # Project source code (empty in template)
├── scripts/ # npm script entry points (jiti TS)
│ └── helpers/ # Shared utilities
│ ├── exec.ts # Command execution with batching
│ ├── root.ts # Project root resolution, execFromRoot
│ ├── type-guards.ts # assertNonNullable, ensureNonNullable
│ ├── eslint.ts # ESLint runner
│ ├── format.ts # dprint runner
│ ├── markdownlint.ts # markdownlint runner
│ └── eslint-rules/ # Custom ESLint rules
├── eslint.config.mts # → scripts/eslint-config.ts
├── commitlint.config.ts # → scripts/commitlint-config.ts
├── .markdownlint-cli2.mjs # → scripts/markdownlint-cli2-config.ts
├── .nano-staged.mjs # → scripts/nano-staged-config.ts
├── tsconfig.json # Extends @tsconfig/strictest
├── dprint.json # Code formatter config
├── cspell.json # Spell checker config
└── .husky/ # Git hooks (pre-commit, commit-msg)
Root config files are thin re-exports — actual logic lives in scripts/.
custom/no-used-underscore-variables— flags_-prefixed parameters/variables that are actually used in the function body.custom/no-async-callback-to-unsafe-return— flags async functions passed as callbacks to parameters withany/unknownreturn type (unhandled promise rejections).
Extends @tsconfig/strictest with:
skipLibCheck: false— checks all declaration files includingnode_modules@total-typescript/ts-reset— fixes built-in type definitionsbetter-typescript-lib— improved standard library typesverbatimModuleSyntax: true— enforces explicitimport type
On every commit, staged files are automatically:
*.{ts,tsx,mts}— linted (eslint --fix) and formatted (dprint fmt)*.md— markdown-linted (markdownlint-cli2 --fix)- All files — spell-checked (
cspell) - Commit message — validated against Conventional Commits