How to Publish Your First NPM Package

Why Create an NPM Package?

Ever built something cool and thought "Hey, I could reuse this in other projects"? That's exactly why you should create an NPM package! I'll show you how to take your code from a local project to a published package that anyone can install with npm install.

Setting Up Your Project

First, create a new directory and initialize your package:

mkdir my-awesome-package
cd my-awesome-package
npm init -y

Now, let's set up TypeScript (because who doesn't want type safety?):

npm install typescript @types/node --save-dev
npx tsc --init

Configuring Your Package

Update your package.json with the essential fields:

{
  "name": "my-awesome-package",
  "version": "1.0.0",
  "description": "A super cool package that does awesome things",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist",
    "README.md"
  ],
  "scripts": {
    "build": "tsc",
    "prepublishOnly": "npm run build"
  },
  "keywords": ["awesome", "cool", "typescript"],
  "author": "Your Name <you@example.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/yourusername/my-awesome-package"
  }
}

And configure TypeScript in tsconfig.json:

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist", "**/__tests__/*"]
}

Writing Your Package Code

Create your source files in the src directory. Here's a simple example:

// src/index.ts
export function greet(name: string): string {
  return `Hello, ${name}! Welcome to my awesome package.`;
}

export function add(a: number, b: number): number {
  return a + b;
}

Testing Your Package

Let's add Jest for testing (because we're professionals here 😎):

npm install jest @types/jest ts-jest --save-dev

Configure Jest in jest.config.js:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/__tests__/**/*.test.ts'],
};

Write some tests:

// src/__tests__/index.test.ts
import { greet, add } from '../index';

describe('my-awesome-package', () => {
  test('greet returns correct greeting', () => {
    expect(greet('John')).toBe('Hello, John! Welcome to my awesome package.');
  });

  test('add returns correct sum', () => {
    expect(add(2, 3)).toBe(5);
  });
});

Add test script to package.json:

{
  "scripts": {
    "test": "jest",
    "build": "tsc",
    "prepublishOnly": "npm run test && npm run build"
  }
}

Creating Documentation

Create a README.md file - this is super important! Here's a template:

# my-awesome-package

A super cool package that does awesome things!

## Installation

```bash
npm install my-awesome-package
```

## Usage

```typescript
import { greet, add } from 'my-awesome-package';

console.log(greet('World')); // Hello, World! Welcome to my awesome package.
console.log(add(2, 3));      // 5
```

## API

### greet(name: string): string
Returns a friendly greeting.

### add(a: number, b: number): number
Adds two numbers together.

## License

MIT © Your Name

Publishing to NPM

Time for the exciting part! Here's how to publish your package:

  1. Create an NPM account if you haven't already:
    npm adduser
  2. Test your package locally:
    npm run build
    npm run test
  3. Check what files will be published:
    npm pack --dry-run
  4. Publish your package:
    npm publish

Pro Tip: Use npm publish --dry-run first to see exactly what would be published without actually publishing it.

Updating Your Package

When you make changes, follow these steps:

  1. Update your code and tests
  2. Update the version in package.json:
    npm version patch  # for bug fixes
    npm version minor  # for new features
    npm version major  # for breaking changes
  3. Publish the update:
    npm publish

Best Practices

  • Always write tests for your code
  • Keep your package focused - do one thing well
  • Use semantic versioning (major.minor.patch)
  • Include clear documentation and examples
  • Add TypeScript types for better developer experience
  • Set up CI/CD for automated testing and publishing

Common Gotchas

  • Package Name: Check if your package name is available on NPM before starting:
    npm search my-awesome-package
  • Scope: If the name is taken, consider using a scope:
    {
      "name": "@yourusername/my-awesome-package"
    }
  • Files: Make sure your files field in package.json includes all necessary files
  • Git Ignore: Don't forget to add dist and node_modules to your .gitignore

Wrapping Up

Congratulations! You've just published your first NPM package. It's an awesome feeling when people start using your code. Remember to:

  • Keep your package maintained
  • Listen to user feedback
  • Add features thoughtfully
  • Document changes in a CHANGELOG.md

Quick Tip: Want to see how your package looks before publishing? Use npm link to test it locally in another project first!