Scaffold TypeScript npm packages using this template to bootstrap your next library.
Built with ESBuild for blazing fast builds and Rollup for bundled type definitions with watch mode support.
Use this template via GitHub's "Use this template" button or:
gh repo create <name> --template="https://github.com/jasonsturges/esbuild-typescript-npm-package"Important: Check package name availability before you start to avoid renaming later:
npm search <term>The following tasks are available:
npm run build- Build production distributable (JS + types)npm run dev- Watch mode for both JS and types (rebuilds on file changes)npm run serve- Start dev server at http://localhost:3000 with live examplesnpm run build:js- Build only JavaScript bundles (all formats)npm run build:types- Build only TypeScript declarations (single bundled .d.ts)
This template builds multiple distribution formats:
- ESM (
dist/index.es.js) - Modern ES modules - CommonJS (
dist/index.cjs.js) - Node.js compatibility - UMD (
dist/index.umd.js) - Universal module definition - IIFE (
dist/index.iife.js) - Browser global variable - Types (
dist/index.d.ts) - Single bundled TypeScript declaration file
Export everything from the top-level index.ts for inclusion in the build.
For example, if you have a utils/ folder with an arrayUtils.ts file:
// src/utils/arrayUtils.ts
export const distinct = <T>(array: T[] = []) => [...new Set(array)];Include that export in the top-level index.ts:
// src/index.ts
export { distinct } from "./utils/arrayUtils"Multiple strategies for development are available.
The examples/ folder provides a local development environment with a dev server:
npm run serveThis starts a dev server at http://localhost:3000 with:
- Live rebuilding on file changes
- Serves static assets from the
examples/folder - Perfect for rapid prototyping and testing
Edit examples/index.ts to test your library. Only exports from src/index.ts are included in the production build.
For development with npm link or when working with other projects:
npm run devThis runs both JavaScript and TypeScript builds in watch mode, automatically rebuilding on file changes. Both JS and types are rebuilt, making this ideal for linked package development.
To test your library in other projects before publishing:
-
From this library: Start watch mode and link the package
npm run dev npm link
-
From your app: Link to this library
npm link "mylib"
A symlink is created in your app's node_modules/. Changes to your library are automatically rebuilt and reflected in your app.
From you library, pack it to create a tarball:
npm packThis will create a [name].tgz tarball that includes the result of what will be uploaded to npm.
Install the pack file in a test app:
npm install [name].tgzOnce development completes, unlink both your library and test app projects.
- From your app: run
npm unlink "mylib"oryarn unlink "mylib"command to remove the library symlink - From your library: run
npm unlinkoryarn unlinkcommand to unregister the package
If you mistakenly forget to unlink, you can manually clean up artifacts from yarn or npm.
For yarn, the link command creates symlinks which can be deleted from your home directory:
~/.config/yarn/link
For npm, the link command creates global packages which can be removed by executing:
sudo npm rm --global "mylib"Confirm your npm global packages with the command:
npm ls --global --depth 0For your app, simply reinstall dependencies to clear any forgotten linked packages. This will remove any symlinks in the node_modules/ folder.
Update your package.json to the next version number and tag a release.
Assure that your package lockfile is also updated by running an install. For npm, this will assure the lockfile has the updated version number. Yarn does not duplicate the version number in the lockfile.
Assure either a .npmrc or publishConfig in your package.json:
package.json:
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"scope": "username"
"access": "public",
}If you are publishing to a private registry such as GitHub packages, update your package.json to include publishConfig and repository:
package.json:
"publishConfig": {
"registry": "https://npm.pkg.github.com/@MyOrg"
}Before publishing, ensure a clean build:
rm -rf dist
npm run buildVerify your package name is available:
npm search <term>Once ready to publish:
npm login
npm publish --access publicFor continuous integration with GitHub Actions, create a .github/workflows/publish.yml
For public NPM packages, use the following workflow:
name: Publish Package to npmjs
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}For private GitHub packages, use the following workflow:
name: Publish Package to GitHub Packages
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: "https://registry.npmjs.org"
scope: "@MyOrg"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: npm ci
- run: npm run build
- run: npm publishThis will deploy your build artifact when a release is tagged.
Obtain an "Automation" CI/CD access token to bypass 2FA from npm by selecting your profile image in the upper right, and chosing "Access Tokens".
To add secrets to your repository:
- From your repository, select Settings
- From the Security section of the sidebar, expand Secrets and variables and select Actions
- From the Secrets tab, press New repository secret to add the
NPM_TOKENkey
To add secrets to your organization:
- From your organization, select Settings
- From the Security section of the sidebar, expand Secrets and variables and select Actions
- From the Secrets tab, press New organization secret to add the
NPM_TOKENkey
For more information, see: