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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@alcalzone/pak

v0.11.0

Published

Programmatic wrapper around popular Node.js package managers

Readme

pak

Programmatic wrapper around popular Node.js package managers

Supports:

  • [x] npm
  • [x] Yarn Classic
  • [x] Yarn Berry

(not all features are available for all package managers)

Usage

Auto-detect the correct package-manager to use

import { detectPackageManager } from "pak";

async function main() {
	// Use the current working directory
	const pak = await detectPackageManager();

	// Or use a different directory. The package manager will default to that dir
	const pak = await detectPackageManager({ cwd: "/path/to/dir" });
}

detectPackageManager takes an options object with the following properties:

{
	/** The working directory for the package manager. Detection will start from here upwards. */
	cwd?: string;
	/** Whether to change the `cwd` to operate in the package's root directory instead of the current one. */
	setCwdToPackageRoot?: boolean;
	/** If this is `false` and no package manager with a matching lockfile was found, another pass is done without requiring one */
	requireLockfile?: boolean;
}

Create an instance of a specific package manager

import { packageManagers } from "pak";
const pak = new packageManagers.npm();

Package manager properties

All package managers share the following properties: | Property | Type | Description | ---------------------------------------------------------------- | -------- | --------- | | cwd | string | The directory to run the package manager commands in. Defaults to process.cwd() | | loglevel | "info" \| "verbose" \| "warn" \| "error" \| "silent" | Which loglevel to pass to the package manager. Note: Not every package manager supports every loglevel. | | stdout | WritableStream | A stream to pipe the command's stdout into. | | stderr | WritableStream | A stream to pipe the command's stderr into. | | stdall | WritableStream | A stream to pipe the command's stdout and stderr into in the order the output comes. | | environment| "production" | "development" | In an production environment, pak avoids accidentally pulling in devDependencies during install commands. |

Install one or more packages

const result = await pak.install(packages, options);

If packages is empty or undefined, this will install the packages that are defined in package.json in the cwd.

Uninstall one or more packages

const result = await pak.uninstall(packages, options);

Update one or more packages

const result = await pak.update(packages, options);
  • packages is an array of package names, like ["pak", "fs-extra"]. If no packages are given, all packages in the current workspace are updated.
  • options: See common options for details.

Recompile native packages

const result = await pak.rebuild(packages, options);
  • packages is an array of package names, like ["pak", "fs-extra"]. If no packages are given, all packages in the current workspace are rebuilt.
  • options: See common options for details.

Pin transitive dependencies to a fixed version

const result = await pak.overrideDependencies(overrides);
  • overrides is an object of packages and exact versions, like {"pak": "1.2.3"}

Sometimes it is necessary to update transitive dependencies, meaning dependencies of dependencies. This command changes all occurences of the given overridden dependencies in the current node_modules tree so that the packages have the specified versions. How it works depends on the package manager:

  • yarn uses the built-in "resolutions" property for package.json
  • npm patches the root package-lock.json and package.json for all dependents of the overridden packages

Note: This command does not support version ranges and it does not check whether the overrides are compatible with the version specified in package.json.

Result object

The returned value is an object with the following properties:

interface CommandResult {
	/** Whether the command execution was successful */
	success: boolean;
	/** The exit code of the command execution */
	exitCode: number;
	/** The captured stdout */
	stdout: string;
	/** The captured stderr */
	stderr: string;
}

Common options

These options are used to influence the commands' behavior. All options are optional:

| Option | Type | Description | Default | Commands | | ---------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------- | | dependencyType | "prod" \| "dev" | Whether to install a production or dev dependency. | "prod" | all | | global | boolean | Whether to install the package globally. | false | all | | exact | boolean | Whether exact versions should be used instead of "^ver.si.on". | false | install | | ignoreScripts | boolean | Prevent execution of pre/post/install scripts. | false | install | | force | boolean | Pass the --force flag to the package manager where applicable. The specific behavior depends on the package manager. | false | install | | additionalArgs | string[] | Additional command line args to pass to the underlying package manager. | none | install, uninstall |

Find the nearest parent directory with a package.json

await pak.findRoot();
await pak.findRoot("lockfile.json");

Returns a string with a path to the nearest parent directory (including cwd) that contains a package.json (and a lockfile if one was specified). Throws if none was found.

Stream the command output

You can stream the command output (stdout, stderr or both) during the command execution, as opposed to getting the entire output at the end. To do so, set the stdout, stderr and/or stdall properties of the package manager instance to a writable stream. Example:

import { PassThrough } from "stream";
import { packageManagers } from "../../src/index";

const pak = new packageManagers.npm(); // or the automatically detected one
pak.stdall = new PassThrough().on("data", (data) => {
	// For example, log to console - or do something else with the data
	console.log(data.toString("utf8"));
});

// execute commands

Get the version of the package manager

const version = await pak.version();

Returns a string with the package manager's version.

Get the paths of all workspaces in the current monorepo

const workspaces = await pak.workspaces();

Returns an array of strings including the paths of all workspaces in the current monorepo. This will return an empty array if the current directory is not part of a monorepo. A folder will be considered a workspace if it contains a file package.json and it is referenced in the workspaces property of the root package.json.

Pack a project or monorepo package into an installable tarball

const result = await pak.pack(options);

options are optional and control what gets packed where and has the following shape:

interface PackOptions {
	/**
	 * In monorepos, this determines which workspace to pack. Defaults to the current working directory.
	 * This must be a path relative to the repo root.
	 */
	workspace?: string;
	/** Where to save the packed tarball. Defaults to the current working directory */
	targetDir?: string;
}

result is a CommandResult (see above) where the stdout contains the absolute path of the packed tarball.