DEV Community

Insaf
Insaf

Posted on

How to Create, Test, and Publish an NPM Package with TypeScript

If you are a Node.js developer, you use 3rd-party packages in your day-to-day projects.

But… do you know how to create your own NPM package?

In this article, I’m going to demonstrate how to:

  • create
  • test
  • publish

your own NPM package: string-manipulate

πŸš€ 1. Create a New NPM Project

mkdir string-manipulate
cd string-manipulate
npm init -y
Enter fullscreen mode Exit fullscreen mode

This generates a basic package.json file

πŸ“¦ 2. Add TypeScript to the Project

Install TypeScript and types for Node:

npm install typescript --save-dev
npm install @types/node --save-dev
Enter fullscreen mode Exit fullscreen mode

Initialize TypeScript:

npx tsc --init
Enter fullscreen mode Exit fullscreen mode

Update tsconfig.json to ensure proper module resolution for publishing:

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "CommonJS",
    "declaration": true,
    "outDir": "./dist",
    "strict": true
  },
  "include": ["src"]
}
Enter fullscreen mode Exit fullscreen mode

πŸ“ 3. Add Your Source Code

Create the folder structure:

mkdir src
Enter fullscreen mode Exit fullscreen mode

Create your main file: src/index.ts

export function reverse(str: string): string {
  return str.split("").reverse().join("");
}

export function capitalize(str: string): string {
  if (!str) return "";
  return str[0].toUpperCase() + str.slice(1);
}
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ 4. Add Tests (Optional but Recommended)

Let's use Jest.
Install Jest with TypeScript support:

npm install --save-dev jest ts-jest @types/jest
Enter fullscreen mode Exit fullscreen mode

Initialize Jest config:

npx ts-jest config:init
Enter fullscreen mode Exit fullscreen mode

Create a test: tests/index.test.ts

import { reverse, capitalize } from "../src";

test("reverse string", () => {
  expect(reverse("hello")).toBe("olleh");
});

test("capitalize string", () => {
  expect(capitalize("hello")).toBe("Hello");
});
Enter fullscreen mode Exit fullscreen mode

Run tests:

npm test
Enter fullscreen mode Exit fullscreen mode

πŸ›  5. Build the Project

Add this script to package.json:

"scripts": {
  "build": "tsc",
  "test": "jest"
}
Enter fullscreen mode Exit fullscreen mode

Now run:

npm run build
Enter fullscreen mode Exit fullscreen mode

This generates compiled files in dist/

πŸ“€ 6. Prepare for Publishing

Update your package.json:

{
  "name": "string-manipulate",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsc",
    "test": "jest"
  }
}
Enter fullscreen mode Exit fullscreen mode

The "types" field allows TypeScript users to automatically get typings.

7. Use your package locally before publishing

run:

npm link
Enter fullscreen mode Exit fullscreen mode

This makes your package available globally as a symlink.
Now, you can install it in your local machine:

npm link string-manipulate
Enter fullscreen mode Exit fullscreen mode

πŸ”„ When you make changes
You only need to run:

npm run build
Enter fullscreen mode Exit fullscreen mode

in your package
The link updates automatically.

πŸ”‘ 8. Login to NPM

npm login
Enter fullscreen mode Exit fullscreen mode

Follow the prompts.

πŸ“¦ 9. Publish the Package

Before publishing, build again:

npm run build
Enter fullscreen mode Exit fullscreen mode

publish:

npm publish
Enter fullscreen mode Exit fullscreen mode

πŸŽ‰ Congratulations β€” your TypeScript-ready NPM package is live!

🎯 10. Using the Package

Anyone can now install it via:

npm install string-manipulate
Enter fullscreen mode Exit fullscreen mode

Example usage:

import { reverse, capitalize } from "string-manipulate";

console.log(reverse("hello")); // olleh
console.log(capitalize("hello")); // Hello
Enter fullscreen mode Exit fullscreen mode

πŸ“š Final Thoughts

Publishing your own package is a great way to share utilities across projects β€” or even with the world. With TypeScript support built in, your users get type safety and better DX out of the box.

If you'd like, I can also help you:

  • βœ… add GitHub Actions for auto-publishing
  • βœ… configure semantic-release
  • βœ… create a README template

Just ask!

Top comments (0)