TypeScript NPM Package Publishing: A Beginner’s Guide
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
- 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 pressEnter
to move to the next. In this casenpm-demo-ts
was available
- The next field is
version
the default value is1.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
- Install your package dependencies, run the following command
npm install --save-dev typescript ts-node
(npm users) oryarn add -D typescript ts-node
(for yarn users) - Setup your
tsconfig.json
, run the following commandnpx tsc --init
, it will create a tsconfig file in the base of your project.
Update theoutDir
field to"dist"
- Create your
src
folder and create yourindex.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 of8
in your console. After that delete theconsole.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 -D
oryarn add tsup --dev
- Create your
tsup.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
oryarn build
- Update the
main
in yourpackage.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
oryarn 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 anadd.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
oryarn test
. The result should look like the image below
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 casenpm 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.
- 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
- Publish your package with
npm publish
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.