A modern TypeScript CLI starter that demonstrates how to build production-ready command-line tools. The project is designed to serve as a reference for best practices and can be used as a starting point for your own CLI projects.
- ✨ Dual ESM and CommonJS builds with proper module format
- 🎯 Path aliases with
@/*prefix (transformed in output) - 🚀 Fast compilation with SWC
- 🧪 Comprehensive testing with 100% code coverage
- 📝 Formatting and linting with Biome
- 🔧 TypeScript 5.x with strict mode
- 📦 Optimized for Node.js 20+
- 🎁 Production-ready publishing configuration
- 📋 Source maps for debugging
To use hello-cli globally, install it via npm:
npm install -g hello-cliFor local development, clone the repo, install dependencies, build, and link:
npm install
npm run build
npm linkOnce installed, the hello-cli command is available globally:
hello-cli hello World
# Output: Hello, World.
hello-cli hello "GitHub Copilot" --yell
# Output: HELLO, GITHUB COPILOT.The main command is hello <name>, which greets the specified name. You can pass --yell or -y to output the greeting in all caps. The CLI also supports standard options like --version and --help for version information and command documentation.
Run npm run build to compile to both ESM and CommonJS. Use npm run build:esm or npm run build:cjs for a single format.
Test with npm test for unit tests or npm run test:integration for build output validation. Use npm run test:cov for coverage details.
Code quality is handled automatically via the prebuild step: npm run typecheck, npm run lint, and npm run format check for issues. Add :fix to any of these commands to auto-fix.
Run npm run clean to remove build artifacts and node_modules.
The dual build system compiles source code once, then generates both ESM and CommonJS outputs. SWC reads the same TypeScript source but uses two separate configurations: .swcrc-esm produces ES modules in build/esm/, while .swcrc-cjs produces CommonJS in build/cjs/. Both preserve the directory structure and include source maps.
Path aliases (@/*) are configured in both SWC configs and resolved to relative imports at compile time via tsc-alias, so they work without TypeScript at runtime.
The entry points (build/esm/src/cli.js and build/cjs/src/cli.js) get shebangs added via a simple Node script in the postbuild step. For CJS, a package.json file is generated in the output to explicitly declare the module format.
Quality checks run before any compilation: npm run build executes the prebuild step (format, lint, typecheck) to ensure only clean code makes it to the output.
- TypeScript 5.x - Language with strict mode
- SWC - Fast TypeScript compiler for dual ESM/CJS
- Commander.js 14.x - CLI framework
- Vitest 4.x - Unit and integration testing
- Biome 2.x - Formatter and linter (replaces ESLint/Prettier)
- tsc-alias - Path alias resolution post-compilation
- Node.js 20+ - Runtime
MIT © Tiberius Silivestru