npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@k13engineering/releasetool

v0.0.7

Published

Build and release tooling for TypeScript npm packages: position-preserving builds with per-file declarations, package.json merging and versioning

Readme

releasetool

CI npm

Tooling for building and releasing TypeScript packages to npm.

  • build: builds a TypeScript project to JavaScript and declaration files, keeping every line and column of the code where it was
  • merge: merges package.json with package.npm.json for publishing
  • patch-version: sets the version in package.json from a git tag

Installation

npm install --save-dev @k13engineering/releasetool

Requires Node.js 20 or newer.

Building

releasetool build --root . --out dist/ --entry lib/index.ts --entry bin/cli.ts

| Option | Description | | ------------ | ----------------------------------------------------------------------------------- | | --entry | Entry file, can be given multiple times. Required. | | --out | Output directory. Required. | | --root | Root directory, the structure below it is kept in the output. Defaults to .. | | --tsconfig | TypeScript configuration for declarations. Defaults to tsconfig.json in the root. |

Paths are relative to the working directory. The options are the same as for deno-node-build, so releasetool build can be used as a drop-in replacement.

What the build does

All files reachable through relative imports from the entry files are built into the output directory:

| Source | Output | | -------------------------------- | --------------------------------------------------------- | | .ts, .mts | .js, .mjs with types stripped, plus .d.ts, .d.mts | | .js, .mjs, .d.ts, .d.mts | copied, relative imports of TypeScript files rewritten | | .json | copied unchanged |

  • Positions are preserved. Types are replaced by whitespace using ts-blank-space, and imports such as "./foo.ts" are rewritten to "./foo.js", which has the same length. Stack traces of the built code therefore point to the same line and column as in the TypeScript source, without source maps.
  • One declaration file per TypeScript file. Declarations are generated by the TypeScript compiler for all files as one program, so types inferred from other modules or packages resolve correctly. The project's tsconfig.json is honored, except for options that control what and where to emit.
  • Type-only imports are followed, so declarations of files that are only imported for their types are part of the output.
  • Nothing is written if the build fails.

The build does not type-check, use tsc --noEmit for that.

Limitations

  • Only erasable TypeScript syntax is supported, the same subset Node.js runs natively. Enums, namespaces with values, parameter properties, import x = require() and <T>value assertions are rejected with their location. Enabling the erasableSyntaxOnly compiler option surfaces most of these in your editor already.
  • Only static specifiers are followed: imports, re-exports and import() with a string literal. import.meta.resolve(), require() and computed import() specifiers are left alone.
  • Imports must not leave the root directory and must include the file extension, as required by Node.js for ES modules.

Publishing

releasetool merge --local-package-json package.json --npm-package-json package.npm.json --output package.json
releasetool patch-version --package-json package.json --package-version v1.2.3

merge combines both files, with fields of package.npm.json taking precedence. patch-version expects the version with a v prefix, as in git tags.

This separates development from publishing: package.json points main and bin to the TypeScript sources, so the package can be run and tested directly with Node.js, while package.npm.json holds the package metadata and points to the built files in dist/.

A GitHub workflow publishing on every pushed tag:

- run: npm ci
- run: npm run build # e.g. releasetool build --out dist/ --entry lib/index.ts
- run: node node_modules/.bin/releasetool merge --local-package-json package.json --npm-package-json package.npm.json --output package.json
- run: node node_modules/.bin/releasetool patch-version --package-json package.json --package-version ${{ github.ref_name }}
- run: npm publish

Usage from code

import { build, stripTypes, mergePackageJson, patchPackageJsonVersion, runCli } from "@k13engineering/releasetool";

// paths of entry points and tsconfig are relative to the root directory
const { files } = await build({
  rootDirectory: ".",
  outputDirectory: "dist",
  entryPoints: ["lib/index.ts"],
});

const javaScript = stripTypes({ code: "const a: number = 1;", fileName: "a.ts" });
// "const a         = 1;"

const merged = mergePackageJson({ localPackageJson, npmPackageJson });
const patched = patchPackageJsonVersion({ packageJson: merged, versionTag: "v1.2.3" });

// runs the CLI without touching the process, e.g. for wrapping it
const { exitCode } = await runCli({
  args: ["build", "--out", "dist", "--entry", "lib/index.ts"],
  stdout: (text) => console.log(text),
  stderr: (text) => console.error(text),
});

All functions throw on errors.

Development

npm ci
npm run build       # builds releasetool with itself
npm run type-check
npm test            # requires 100% coverage
npm run lint

The project follows node-boilerplate.

License

LGPL-2.1-only