Creating and publishing an NPM package can enhance your portfolio and allow you to share reusable code with the community. Recently I released my own first package, a manga web reader (github.com/Mangatsu/mangatsu-reader) that is still very much experimental. This guide will walk you through setting up a repository for a TypeScript project, as well as configuring the project with useful linting software, and finally how to build and publish your package to NPM.
As for npm packages, usually MIT (or ISC) is recommended for the straightforwardness and ease of use. Sometimes, depending on the use case, Apache 2.0 with patent grant or strong copyleft license like (A)GPL 3.0 might fit your needs as well. Be sure to remember to create the LICENSE (or COPYING) file!
npm init.
mkdir name-of-the-package
cd name-of-the-package
npm init -ypackage.json file with default configurations.git init and create .gitignore filenpm install --save-dev typescript @types/node rimraftsconfig.json file for your TypeScript configuration.
{
"compilerOptions": {
/* Language and Environment */
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["node", "react"],
"jsx": "react",
"useDefineForClassFields": true,
/* Modules */
"module": "ESNext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": false,
"resolveJsonModule": true,
/* JavaScript Support */
"allowJs": false,
/* Emit */
"declaration": true,
"outDir": "./lib",
"declarationDir": "./lib",
/* Interop Constraints */
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
/* Type Checking */
"strict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true,
/* Completeness */
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "lib"]
}src directory and outputs them into the lib directory.npm install --save-dev prettier eslint prettier-eslint @typescript-eslint/parser @typescript-eslint/eslint-plugineslint.config.mjs:
{
"semi": false,
"trailingComma": "all",
"singleQuote": false,
"tabWidth": 2,
"useTabs": false,
"printWidth": 120,
"endOfLine": "lf"
}npm install --save-dev husky lint-staged
npx husky install"lint-staged": {
"*.{ts,tsx,js,jsx}": "eslint --cache --fix",
"*.{ts,tsx,js,jsx,css,md}": "prettier --write"
}"scripts": {
"prepare": "husky"
}echo "npx lint-staged" > .husky/pre-commit"scripts": {
"tsc": "tsc -p tsconfig.json",
"clean": "rimraf lib && rimraf build",
"build": "npm run clean && npm run tsc"
}npm run build will compile your TypeScript files from src to the lib directory."scripts": {
"copy-assets": "node -e \"require('fs').cpSync('./src/assets', './lib/assets', {recursive: true});\"",
}"scripts": {
"build": "npm run clean && npm run tsc && npm run copy-assets"
}npm login{
"name": "name-of-the-package",
"version": "0.1.0",
"description": "",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"type": "module",
"files": [
"lib/"
],
"repository": {
"type": "git",
"url": "github.com/<user,org>/<name-of-the-package>"
},
"keywords": [
"typescript"
],
"author": "Marko Kristian Leinikka",
"license": "MIT"
}npm publish. If it's your first time publishing, you can use npm publish --access public to make it publicly accessible.You've now created a TypeScript NPM package with linting, formatting, pre-commit hooks, and a build process that handles asset copying. Whether you're publishing utility functions or a full-fledged library, this setup will help ensure a smooth workflow and quality code.
By following this guide, you should now be able to confidently publish your TypeScript packages to NPM and manage a clean, maintainable codebase.