npm.io
1.3.1 • Published 3d agoCLI

@atharvdange/toolchain

Licence
MIT
Version
1.3.1
Deps
3
Size
52 kB
Vulns
0
Weekly
0

@atharvdange/toolchain

A reusable CLI that scaffolds a complete dev toolchain - ESLint, Prettier, Husky, commitlint, and strict TypeScript - into any JS/TS project with one command.

pnpm dlx @atharvdange/toolchain init

Features

  • Framework-aware - detects Next.js, Express, React, or plain TS and tailors ESLint rules accordingly
  • Monorepo-ready - detects workspaces / pnpm.workspaces and generates tsconfig project references with per-package eslint overrides
  • Zero-config - interactive prompts guide you through, or use --yes to skip
  • All in one - linter, formatter, hooks, commit linting, and type checking
  • Project scaffolding - create new projects from scratch with scaffold command
  • Opinionated defaults - strict TypeScript config, sensible ESLint rules, proper monorepo structure

Commands

init - Add toolchain to existing project
# Interactive
pnpm dlx @atharvdange/toolchain init

# Non-interactive (defaults)
pnpm dlx @atharvdange/toolchain init --yes
scaffold - Create a new project
# Create a React project with npm
pnpm dlx @atharvdange/toolchain scaffold my-app --template react --pm npm

# Create a Next.js project with pnpm
pnpm dlx @atharvdange/toolchain scaffold my-app --template nextjs --pm pnpm

# Create a plain TypeScript project
pnpm dlx @atharvdange/toolchain scaffold my-app --template plain

# Create a monorepo with Turborepo
pnpm dlx @atharvdange/toolchain scaffold my-app --template turbo --pm pnpm

# Interactive template selection
pnpm dlx @atharvdange/toolchain scaffold my-app
Available templates
Template Description Source
plain Basic TypeScript project Generated by toolchain
react React 19 with Vite and TypeScript create-vite
nextjs Next.js 15 with App Router create-next-app
express Express 5 REST API with TypeScript Generated by toolchain
pnpm-monorepo pnpm workspaces monorepo with apps and packages Generated by toolchain
turbo Turborepo monorepo with apps and packages Generated by toolchain
Package managers

Use --pm to specify the package manager: npm, pnpm, yarn, or bun.

Note: React and Next.js projects use their official scaffolding tools (create-vite and create-next-app), then the toolchain is added on top.

Note: pnpm-monorepo template requires pnpm and will override --pm if set to a different package manager.

Monorepo structure

Both pnpm-monorepo and turbo templates generate a standard monorepo structure:

my-app/
├── apps/
│   ├── web/          # Web application
│   ├── mobile/       # Mobile application
│   └── api/          # API server
├── packages/
│   ├── shared/       # Shared utilities (logger, formatDate)
│   ├── config/       # Environment configuration (typed)
│   └── db/           # Database client
├── pnpm-workspace.yaml
├── turbo.json        # (turbo only)
└── package.json

Each package has its own package.json, tsconfig.json, and source files with workspace dependencies wired up.

What it sets up

Config Generated variant
.editorconfig Static
.prettierrc / .prettierignore Static
commitlint.config.js Static
eslint.config.mjs Plain TS / React / Next.js / Express rules, ignores .expo/
tsconfig.json Strict config with project references (monorepo)
.husky/pre-commit lint-staged + typecheck
.husky/commit-msg commitlint
package.json Scripts, lint-staged config, devDependencies

TypeScript configuration

The generated tsconfig.json includes strict options:

Option Description
strict Enable all strict type-checking options
noUnusedLocals Error on unused local variables
noUnusedParameters Error on unused function parameters
noFallthroughCasesInSwitch Error on fallthrough cases in switch statements
noUncheckedIndexedAccess Add undefined to any untyped index access
noImplicitOverride Require override keyword in derived classes
exactOptionalPropertyTypes Distinguish between undefined and missing props
noPropertyAccessFromIndexSignature Force bracket notation for index signatures
verbatimModuleSyntax Enforce import type for type-only imports
moduleResolution: bundler Modern module resolution for bundlers

ESLint variants

The generated eslint.config.mjs adapts based on what's in your package.json:

Detected Plugins included
Plain TS typescript-eslint, unicorn, perfectionist
React Above + eslint-plugin-react, eslint-plugin-react-hooks
Next.js Above + @next/eslint-plugin-next
Express Same as Plain TS but no-unsafe-* rules relaxed to warn

Ignored directories: node_modules, dist, .next, build, .expo, .pnpm-store, *.config.*, .env*

For monorepos, also ignores **/packages/*/dist/**.

Detection logic

  • Package manager: checks npm_config_user_agent first (set by the package manager that invoked the CLI), then lockfiles (pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lockb → bun), then devEngines in package.json, else npm
  • Monorepo: checks for workspaces in package.json or pnpm.workspaces
  • Framework: checks dependencies / devDependencies for next, express, react

Troubleshooting

Husky hooks not running after git init

If you delete .git and re-initialize with git init, husky hooks will stop working. Run:

pnpm run prepare

This reconfigures core.hooksPath to point to .husky.

npx fails with EBADDEVENGINES

npx @atharvdange/toolchain init will not work when the package's packageManager is set to pnpm (if you initialized a blank project with pnpm init), causing npm to throw an EBADDEVENGINES error. Use pnpm dlx, yarn dlx, or bunx instead.

Keywords