Skip to content

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

  1. Generate token at npmjs.com/settings/tokens
  2. Add to GitHub Secrets as NPM_TOKEN
  3. 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

  1. Update README with installation instructions
  2. Add changelog entry for new version
  3. Update GitHub release notes
  4. 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

Released under the MIT License.