Publishing a Typescript package to NPM in 2023

December 13th, 2023

Recently I wrote a small Typescript package, youtube-subtitle-transcript, that fetches the transcripts of YouTube videos. I wanted to publish it to npm so that I could import it into some of my other projects and share it with others. However, it had been a while since I had published anything to npm so I had forgotten how it all works. Now that it’s published, I’ve consolidated all of my notes below.

Packaging for ESM and CJS with tsup

ECMAScript modules (ESM) may be the future but CommonJS (CJS) is still around and I wanted to package my library for both. The tool that I landed on for this is tsup. Install it as a dev dependency (npm i tsup -D) . Assuming that the entry file for the library is index.ts, in your package.json file, specify the main entry points of the package:

"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
  ".": {
    "require": "./dist/index.js",
    "import": "./dist/index.mjs",
    "types": "./dist/index.d.ts"
  }
},
"scripts": {
  "build": "tsup index.ts --format cjs,esm --dts --clean"
}

Running this build script will generate a dist folder with the transpiled code for both ESM and CJS.

Testing the package

Before publishing, we can validate the package using publint.dev . This will give you an idea of how compatible it is across environments. Run it locally with npx publint.

Another trick I learned is that you can use the package’s path in the package.json of another project to test it works locally. In the other project, this would look like:

dependencies: {
  "new-package": "file:/Users/michael/new-package"
}

And then do an npm install. This links the dist directory of the package locally to your project. If you rebuild the package, this will be immediately reflected in the project

Publishing to npm

After validating the package, it’s time to push it to npm. This includes:

Specifying what to publish

In the package.json, we can use the files field to specify which files should be included in the published package. Generally, you do not need to include source files in the published package.

The files field in package.json will look something like this:

"files": ["dist", "README.md", "LICENSE"],

Using np for publishing

To publish we need to:

I used to do this all manually and found it to be headache inducing pain. Now I have found np, which markets itself as a better npm publish and really lives up to its name. I installed it globally with sudo npm install -g np and then publish by running np in the project folder and following the prompts - it’s great.