TypeScript NPM Package Publishing: A Beginner’s Guide

Paul Ehikhuemen
7 min readJun 12, 2023

--

Image of NPM registry and Node.js and Typescript

What is NPM?

NPM (Node Package Manager) is the default package manager for the JavaScript programming language. The NPM registry is a public repository that serves as a central hub for storing and distributing JavaScript packages. It allows developers to easily install, manage, and share reusable JavaScript code packages, also known as modules or packages.

What is Typescript and why should you use it?

TypeScript is a programming language developed by Microsoft. It is a superset of JavaScript, meaning that any valid JavaScript code is also valid TypeScript code. It offers advantages over plain JavaScript by providing:

  • Static typing
  • Improved IDE support
  • Enhanced code quality
  • Access to advanced language features
  • Better tooling
  • Improved collaboration.

These benefits enhance the development experience for NPM packages and make it easier for users of the packages to consume and integrate them into their projects, leading to more reliable, scalable, and maintainable JavaScript applications.

In this article you will learn how to create your own NPM Package with Typescript and how to publish it to the NPM registry.

Setting up a Typescript project

  • Create a new project directory on your local machine.
  • Open a terminal or command prompt and navigate to the project directory.
  • Run the following command to initialize a new Node.js project npm init and follow the on screen instructions
Result of “npm init” command
  • The first field is package name , this should be a unique name for your package. You can check to see if the name is available by searching the NPM registry. If the name is available, you press Enter to move to the next. In this case npm-demo-ts was available
Search for ‘npm-demo-ts’ in NPM registry
  • The next field is version the default value is 1.0.0 . Package versions generally use Semantic Versioning.

What is Semantic Versioning?

It provides a standard way to convey the compatibility and changes in a package across different releases. It consists of three numerical components: Major version, Minor version, and Patch version, represented as MAJOR.MINOR.PATCH e.g 1.0.7

  • MAJOR version increment: Introduce incompatible changes.
  • MINOR version increment: Add new features in a backward-compatible manner.
  • PATCH version increment: Make backward-compatible bug fixes or minor updates.

By following semantic versioning practices and using version constraints, developers can manage dependencies effectively, ensure compatibility, and communicate the impact of package updates to users and consumers of NPM packages.

  • The next field is description , which should contain a short description of what your NPM package does.
  • The next field is entry point , which refers to the main Javascript file that will be executed when the package is imported by another module.
    You can leave the default for now.
  • The next field is test command , which is the command or script that should be executed to run tests for your package. You can also leave the default for now.
  • The next field is git repository which should contain a link to the remote Git repository
  • The next field is keywords which should contain words that are relevant to your package to help with indexing in the NPM registry
  • The next field is author which is the name of the package author
  • The last field is license which should contain your open source license. You can read more about licenses here or just leave the defaults for now
  • After this you should get a summary of all your answers it should look like the image below but filled with your answers. Hit Enter and let’s move on
Summary of package.json
  • Install your package dependencies, run the following command npm install --save-dev typescript ts-node (npm users) or yarn add -D typescript ts-node (for yarn users)
  • Setup your tsconfig.json , run the following command npx tsc --init , it will create a tsconfig file in the base of your project.
    Update the outDir field to "dist"
  • Create your src folder and create your index.ts file and paste in the code below, it is a simple function to add 2 numbers.
export function add(a: number, b: number): number {
return a + b;
}

console.log(add(3, 5)); //output: 8
  • Run the code with the following command npx ts-node src/index and you should see the result of 8 in your console. After that delete the console.log line in your code.
  • Initialise your git repo with git init
  • Create a .gitignore file and paste the following into the file
/node_modules

# Ignore test-related files
/coverage.data
/coverage/

# Build files
/dist
  • It is also a good idea to create a README.md file that will contain a description of your project and how to use it.

Building your Typescript package

Now you are done writing the code of your package, we will move on to how to build your package for the end users to be able to consume it in their various javascript or typescript projects.

There are various dedicated build tools that can help with this process such as tsup, babel, webpack, rollup and so on but in this article I’ll focus on tsup

Setting up Tsup

  • Add tsup to your project by running the following command,
    npm install tsup -Dor yarn add tsup --dev
  • Create yourtsup.config.ts file and paste the code below
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs", "esm"], // Build for commonJS and ESmodules
dts: true, // Generate declaration file (.d.ts)
splitting: false,
sourcemap: true,
clean: true,
});
  • Update the scripts in your package.json with the following
 "scripts": {
"build": "tsup",
"test": "echo \"Error: no test specified\" && exit 1"
},
  • You can now build your project by running npm run build or yarn build
  • Update the main in your package.json and add the following:
...
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
...
  • Now your package should be all ready for publishing but before that we have to test the package to ensure everything is working as planned

Testing your NPM package

Testing enables you to catch and address any issues or bugs before they reach your users. To write tests for your npm package you will need to setup Jest.

Setting up Jest

  • Add jest to your project by running the following command
    npm install -D jest ts-jest @types/jest or yarn add -D jest ts-jest @types/jest
  • Add a jest.config.js file to your project and past the following
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
};
  • Create a tests folder in your project, and create an add.test.ts file and add the following test
import { add } from '../src';

test('adds two numbers correctly', () => {
const result = add(2, 3);
expect(result).toBe(5);
});
  • Update your package.json file with the following scripts
"scripts": {
"build": "tsup",
"test": "jest"
},
  • Run your test script with the following command npm run test or yarn test . The result should look like the image below
Result of running our test command

Now you are successfully done writing and testing your npm package, let’s move on to publishing your NPM package.

Publishing your NPM Package

One last thing, before publishing your package to the NPM registry it is important to publish it and test it on your local machine to ensure its correctness, functionality, and compatibility with other modules or dependencies. Local testing allows you to catch any issues or bugs early on and make necessary improvements before releasing your package to the public

Publishing your NPM package locally

  • Run the following command at the root of your package
    npm link
  • Create another test project and link the npm package locally with
    npm link name-of-package in this case npm link npm-demo-ts
  • Create a main.ts file in your test project and import your package to test it out. You should also type information in your project, one of the many perks of typescript.
Result for linking npm package locally
  • Now you are done testing locally, let’s publish to the registry

Publishing your NPM package to the NPM registry

  • Create an account on NPM if you don’t already have one.
  • Login to your NPM account in the command line with
    npm login
  • Enter your username, password, email and OTP
Successful NPM Login via CLI
  • Publish your package with npm publish
Result of successful npm publish
Search result for npm package in the registry

Conclusion

Using TypeScript for package development and consumption brings numerous benefits. Its static typing empowers developers with improved code quality, early error detection, and enhanced editor support. TypeScript’s type definitions enable better documentation and increased understanding of package APIs, facilitating seamless integration and reducing potential bugs for consumers. Additionally, TypeScript’s ecosystem boasts a wide range of libraries, tools, and resources, fostering collaboration and community support.

By publishing your first TypeScript NPM package, you not only benefit from these advantages but also contribute to the growth and enrichment of the TypeScript ecosystem. Join the vibrant community, share your knowledge and expertise, and make a lasting impact on the world of JavaScript development.

Thank you for reading! Follow me for more tutorials.

--

--

Paul Ehikhuemen
Paul Ehikhuemen

Written by Paul Ehikhuemen

Software engineer | Creative Developer | Exploring the Blockchain.