NPM Publishing
Guide for publishing the TypeScript project template as an NPM package.
Overview
The template is configured for easy NPM publishing with proper TypeScript support, including:
- Declaration files (
.d.ts
) for TypeScript consumers - Source maps for debugging
- Clean package structure with only necessary files
- Proper entry points for different module systems
Package Configuration
Package.json Setup
json
{
"name": "your-package-name",
"version": "1.0.0",
"description": "Your package description",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"README.md",
"LICENSE"
],
"scripts": {
"prepublishOnly": "npm run build"
}
}
Entry Points
- main:
dist/index.js
- CommonJS entry point - types:
dist/index.d.ts
- TypeScript declarations - module:
dist/index.mjs
- ES modules (optional)
Pre-Publishing Checklist
1. Update Package Information
json
{
"name": "your-unique-package-name",
"version": "1.0.0",
"description": "Clear, concise description",
"keywords": ["typescript", "template", "starter"],
"author": "Your Name <email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/username/repo.git"
},
"bugs": {
"url": "https://github.com/username/repo/issues"
},
"homepage": "https://github.com/username/repo#readme"
}
2. Verify Build Output
bash
# Clean build
npm run clean
npm run build
# Verify output structure
ls -la dist/
# Should contain: index.js, index.d.ts, utils.js, utils.d.ts, etc.
3. Test Package Locally
bash
# Pack without publishing
npm pack
# Install locally in test project
cd ../test-project
npm install ../your-package/your-package-1.0.0.tgz
# Test import
node -e "console.log(require('your-package'))"
Publishing Process
1. Login to NPM
bash
# Login to NPM registry
npm login
# Verify login
npm whoami
2. Dry Run
bash
# Test publish without actually publishing
npm publish --dry-run
# Review what would be published
npm pack --dry-run
3. Publish
bash
# Publish to NPM
npm publish
# Publish with specific tag
npm publish --tag beta
Version Management
Semantic Versioning
- Major (1.0.0 → 2.0.0): Breaking changes
- Minor (1.0.0 → 1.1.0): New features, backward compatible
- Patch (1.0.0 → 1.0.1): Bug fixes, backward compatible
NPM Version Commands
bash
# Patch version (1.0.0 → 1.0.1)
npm version patch
# Minor version (1.0.0 → 1.1.0)
npm version minor
# Major version (1.0.0 → 2.0.0)
npm version major
# Pre-release version (1.0.0 → 1.0.1-beta.0)
npm version prerelease --preid=beta
Automated Publishing
GitHub Actions Workflow
yaml
name: Publish to NPM
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build package
run: npm run build
- name: Publish to NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Setup NPM Token
- Generate token at npmjs.com/settings/tokens
- Add to GitHub Secrets as
NPM_TOKEN
- Set appropriate permissions (Automation or Publish)
Package Optimization
File Inclusion
json
{
"files": [
"dist/**/*",
"README.md",
"LICENSE",
"CHANGELOG.md"
]
}
Exclude Development Files
json
{
"files": [
"dist/**/*"
]
}
This automatically excludes:
src/
(source TypeScript files)__tests__/
(test files)node_modules/
(dependencies)- Configuration files
Bundle Size Optimization
bash
# Analyze package size
npm pack --dry-run
# Check what's included
npx bundlesize
# Optimize dependencies
npm run build -- --analyze
TypeScript Support
Declaration Files
Ensure TypeScript consumers get proper type support:
json
{
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
}
Type-Only Exports
typescript
// For type-only exports
export type { UtilConfig, AsyncResult } from './types.js';
// For runtime exports
export { main } from './index.js';
export { delay, safeJsonParse, formatTimestamp } from './utils.js';
Distribution Tags
Using Tags
bash
# Publish as beta
npm publish --tag beta
# Publish as next
npm publish --tag next
# Promote beta to latest
npm dist-tag add your-package@1.0.0-beta.1 latest
Tag Management
bash
# List tags
npm dist-tag ls your-package
# Add tag
npm dist-tag add your-package@1.0.0 stable
# Remove tag
npm dist-tag rm your-package beta
Post-Publishing
Verify Publication
bash
# Check package info
npm info your-package
# Install and test
npm install your-package
Update Documentation
- Update README with installation instructions
- Add changelog entry for new version
- Update GitHub release notes
- Announce on relevant channels
Troubleshooting
Common Issues
Permission Denied
bash
# Check NPM login
npm whoami
# Re-login if needed
npm logout
npm login
Package Name Conflicts
bash
# Check name availability
npm info your-package-name
# Use scoped package
npm publish --access public
Build Failures
bash
# Clean and rebuild
npm run clean
npm run build
# Check TypeScript errors
npx tsc --noEmit
Recovery Strategies
Unpublish (within 24 hours)
bash
# Unpublish specific version
npm unpublish your-package@1.0.0
# Unpublish entire package (dangerous)
npm unpublish your-package --force
Deprecate Version
bash
# Deprecate version
npm deprecate your-package@1.0.0 "This version has critical bugs"
Best Practices
Security
- ✅ Use 2FA for NPM account
- ✅ Regularly rotate NPM tokens
- ✅ Audit dependencies before publishing
- ✅ Use
npm audit
in CI/CD
Quality
- ✅ Always run tests before publishing
- ✅ Maintain high test coverage
- ✅ Use semantic versioning consistently
- ✅ Write clear changelog entries
Documentation
- ✅ Keep README up to date
- ✅ Include usage examples
- ✅ Document breaking changes
- ✅ Provide migration guides