Introduction
Creating a new NPM package from scratch involves setting up dozens of configuration files, dependencies, and tooling. What if you could generate a production-ready package structure in seconds? In this post, I'll show you how I built @sargonpiraev/create-npm-package
- a CLI template generator that creates fully configured TypeScript NPM packages with all the modern tooling you need.
The Problem: Repetitive Package Setup
Every time I wanted to create a new NPM package, I had to:
- Set up TypeScript configuration
- Configure ESLint and Prettier
- Add testing with Jest
- Set up Git hooks with Husky
- Configure semantic release
- Add CI/CD pipeline
- Set up conventional commits and commit linting
This process was taking hours and was prone to copy-paste errors. After creating several packages manually, I realized I needed a better solution.
The Solution: A Template Generator CLI
What the Template Includes
My @sargonpiraev/create-npm-package
provides a complete development environment:
Core Technologies:
- TypeScript with ES modules support
- ESLint with latest TypeScript configuration
- Prettier for consistent code formatting
- Jest for testing with coverage reporting
Development Workflow:
- Husky Git hooks for quality control
- Commitlint enforcing conventional commits
- Semantic Release for automated versioning and publishing
- GitLab CI/CD pipeline ready to deploy
Project Structure:
- Proper src/
directory with TypeScript entry point
- Professional package.json
with all necessary scripts
- Complete configuration files for all tools
- MIT license and proper NPM publishing setup
How It Works
The CLI tool works in five simple steps:
1. Argument validation: Takes project name as required argument
2. Directory creation: Creates project folder with conflict detection
3. Template copying: Copies all configuration files from the package
4. Package.json generation: Creates customized package.json with your project name
5. Source setup: Creates src/index.ts
starter file
`typescript
#!/usr/bin/env node
import fs from 'fs'
import path from 'path'
// Get project name from command line
const projectName = process.argv[2]
if (!projectName) {
console.error('Error: Please specify a project name.')
process.exit(1)
}
// Create and populate project directory
const projectDir = path.resolve(process.cwd(), projectName)
// ... file copying and setup logic`
Implementation Deep Dive
Smart File Management
The generator intelligently handles file conflicts:
- Warns if directories or files already exist
- Safely creates nested directory structures
- Handles npm's .gitignore
to .npmignore
renaming issue
Template File Architecture
Key configuration files included:`
.husky/ # Git hooks
├── pre-commit # Runs linting before commits
└── commit-msg # Validates commit messages
.gitlab-ci.yml # CI/CD pipeline
commitlint.config.ts # Conventional commit rules
eslint.config.ts # Latest ESLint configuration
jest.config.ts # Testing setup with coverage
tsconfig.json # TypeScript compilation settings
.prettierrc.json # Code formatting rules
.releaserc.json # Semantic release configuration`
Dynamic Package.json Generation
The generator creates a customized package.json
by:
- Extracting proven scripts and dependencies from the template
- Setting the project name from CLI argument
- Preserving all development tooling configuration
- Setting up proper NPM publishing metadata
Real-World Usage Examples
Quick Start
`bash
Create a new package
npx @sargonpiraev/create-npm-package my-awesome-package
cd my-awesome-package
Install dependencies
npm install
Start developing
npm run dev
Run tests
npm test
Build for production
npm run build
`What You Get Immediately
A complete project ready for:
- Immediate development: TypeScript compilation with watch mode via npm run dev
- Quality control: Automatic linting and formatting on every commit with Husky hooks
- Testing: Jest configured with coverage reporting and XML output for CI
- CI/CD: Complete GitLab pipeline with 4 stages and 6 parallel test jobs
- Publishing: Semantic release automation with conventional commits
- Complete setup: All modern tooling configured and working together
Proven Results
This template has been successfully used to create:
- habitify-api-client: TypeScript client for Habitify API
- habitify-mcp-server: MCP server for Habitify API
Each package generated saved 2-3 hours of initial setup time and ensured consistent tooling across all projects.
CI/CD Pipeline Deep Dive
One of the most valuable features of this template is the production-ready GitLab CI/CD pipeline. Let me break down how it works and why it saves significant development time.
Why GitLab CI?
I chose GitLab CI for this template because it offers an excellent balance of simplicity and power. The YAML configuration is straightforward, everything lives in one place (code, CI/CD, releases), and it has generous free tier for open source projects.
GitHub Integration: If you prefer GitHub, GitLab supports automatic mirroring. You can keep your main repository on GitHub while leveraging GitLab's CI/CD capabilities. I often use this approach myself.
Coming Soon: GitHub Actions support is planned for future releases, giving you more platform options.
Pipeline Architecture
The .gitlab-ci.yml
creates a robust 4-stage pipeline:
🔧 Install Stage`yaml
install:
stage: install
script:
- npm ci --prefer-offline --cache .npm --no-audit --progress=false
artifacts:
paths: [node_modules]
expire_in: 1 day`
🧪 Test Stage (6 parallel jobs)
- Unit tests: Jest with coverage reporting and XML output
- Code formatting: Prettier validation
- Type checking: TypeScript compiler verification
- Linting: ESLint with TypeScript rules
- Security audit: npm audit for vulnerabilities
- Build verification: Ensures compilation succeeds
📦 Build Stage`yaml
build:
stage: build
script:
- npm run build
artifacts:
paths: [build]
expire_in: 1 day`
🚀 Release Stage (main branch only)`yaml
release:
stage: release
script:
- npx semantic-release
rules:
- if: $CI_COMMIT_BRANCH == "main"`
Setting Up Your GitLab Project
Before configuring automated publishing, you need to create a GitLab project:
1. Create new project on GitLab:
- Go to [gitlab.com](https://gitlab.com) and click "New project"
- Choose "Create blank project"
- Set project name (same as your package name)
- Set visibility level (Public for open source packages)
2. Push your generated package:
`bash
cd your-package-name
git init
git add .
git commit -m "feat: initial package setup"
git remote add origin https://gitlab.com/yourusername/your-package-name.git
git push -u origin main
`
Setting Up Automated Publishing
After creating your GitLab project, you need two tokens for the pipeline:
NPM_TOKEN for package publishing:
1. Go to [npmjs.com](https://www.npmjs.com) → Account Settings → Access Tokens
2. Create a new Automation token
3. Add to GitLab CI/CD variables as NPM_TOKEN
GITLAB_TOKEN for releases and tags:
1. Go to GitLab → User Settings → Access Tokens
2. Create token with write_repository
scope
3. Add to GitLab CI/CD variables as GITLAB_TOKEN
Both tokens should be set as protected and masked variables in your GitLab project settings.
Semantic Release Magic
The pipeline uses semantic-release for intelligent versioning:
- fix: commits trigger patch releases (1.0.1)
- feat: commits trigger minor releases (1.1.0)
- BREAKING CHANGE: triggers major releases (2.0.0)
This automatically:
- Analyzes commit messages following [Conventional Commits](https://www.conventionalcommits.org/)
- Determines the next version number
- Generates changelog from commits
- Creates Git tags and releases
- Publishes to NPM registry
Live Pipeline Example
You can see this pipeline in action:
- [Pipeline execution](https://gitlab.com/sargonpiraev/create-npm-package/-/pipelines/1902470330) - Complete build process
- [Automated releases](https://gitlab.com/sargonpiraev/create-npm-package/-/releases) - Generated releases with changelogs
- [Git tags](https://gitlab.com/sargonpiraev/create-npm-package/-/tags) - Automatic version tags
Why This Pipeline Matters
Zero-effort publishing: Once configured, every merge to main automatically:
- Runs comprehensive quality checks
- Publishes new versions based on changes
- Creates detailed releases with changelogs
- Maintains version history
Quality assurance: Every commit is validated through:
- 6 different test jobs running in parallel
- Type safety verification
- Code style consistency
- Security vulnerability scanning
- Build verification
Consistent workflow: Enforces development best practices:
- Conventional commit messages
- Semantic versioning
- Comprehensive testing
- Automated documentation
This pipeline transforms package maintenance from a manual, error-prone process into a fully automated workflow.
Key Features and Benefits
Production-Ready Setup
Every generated package includes:
- Modern TypeScript configuration with ES modules
- Comprehensive linting rules with automatic fixes
- Automated testing pipeline with coverage reports
- Professional Git workflow with conventional commits
- Automated release management with semantic versioning
Developer Experience Optimizations
- Fast setup: From idea to coding in under 30 seconds
- Consistent structure: Every package follows the same proven patterns
- Best practices: Modern tooling and configuration
- Zero maintenance: Template updates automatically benefit future packages
Code Quality Standards
The template enforces:
- Type safety with strict TypeScript settings
- Code quality with ESLint and Prettier
- Commit message standards with conventional commits
- Automated testing and coverage requirements
- Proper NPM package metadata and publishing setup
Future Enhancements
Planned Features
- Interactive prompts: Choose between different template variants
- Multiple platforms: Support for GitHub Actions, Azure DevOps
- Framework options: React, Vue, Node.js server templates
- Custom configurations: Allow template customization options
Community Contributions
The template is open source and welcomes:
- New configuration improvements
- Additional tooling integrations
- Bug fixes and optimizations
- Documentation enhancements
Conclusion
Building @sargonpiraev/create-npm-package
transformed my NPM package creation workflow from hours to seconds. The key was investing upfront in a solid template that includes all modern tooling and best practices.
This foundation enabled rapid development of subsequent packages and has already saved dozens of hours across multiple projects. The template continues to evolve with the TypeScript ecosystem.
Getting Started
Try the template yourself:
`bash
npx @sargonpiraev/create-npm-package your-project-name
cd your-project-name
npm install
npm run dev`
Additional Resources
- [Package on NPM](https://www.npmjs.com/package/@sargonpiraev/create-npm-package)
- [Source Code on GitLab](https://gitlab.com/sargonpiraev/create-npm-package)
- [TypeScript Configuration Guide](https://www.typescriptlang.org/tsconfig)
- [Semantic Release Documentation](https://semantic-release.gitbook.io/)
- [Conventional Commits Specification](https://www.conventionalcommits.org/)