or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cocoapods-package-manager.mdfactory-functions.mdindex.mdnode-package-managers.mdutilities-helpers.md
tile.json

node-package-managers.mddocs/

Node.js Package Managers

Unified interface and implementations for npm, yarn, pnpm, and bun package managers with package manager-specific optimizations and consistent API.

Capabilities

Base Package Manager Interface

All Node.js package managers implement the core PackageManager interface.

interface PackageManager {
  /** The options for this package manager */
  readonly options: PackageManagerOptions;

  /** Run any command using the package manager */
  runAsync(command: string[], options?: SpawnOptions): SpawnPromise<SpawnResult>;
  
  /** Invoke a binary from within a package, like "eslint" or "jest" */
  runBinAsync(command: string[], options?: SpawnOptions): SpawnPromise<SpawnResult>;

  /** Get the version of the used package manager */
  versionAsync(): Promise<string>;
  
  /** Get a single configuration property from the package manager */
  getConfigAsync(key: string): Promise<string>;
  
  /** Remove the lock file within the project, if any */
  removeLockfileAsync(): Promise<void>;
  
  /** Get the workspace root package manager, if this project is within a workspace/monorepo */
  workspaceRoot(): PackageManager | null;

  /** Install all current dependencies using the package manager */
  installAsync(): Promise<SpawnResult> | SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  
  /** Uninstall all current dependencies by removing the folder containing the packages */
  uninstallAsync(): Promise<void>;

  /** Add a normal dependency to the project */
  addAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  
  /** Add a development dependency to the project */
  addDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  
  /** Add a global dependency to the environment */
  addGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;

  /** Remove a normal dependency from the project */
  removeAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  
  /** Remove a development dependency from the project */
  removeDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  
  /** Remove a global dependency from the environments */
  removeGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
}

interface PackageManagerOptions extends SpawnOptions {
  /** If the package manager should run in silent mode */
  silent?: boolean;
  /** The logging method used to communicate the command which is executed */
  log?: (...args: any[]) => void;
}

Base Package Manager Class

Abstract base class providing common functionality for all Node.js package managers.

abstract class BasePackageManager implements PackageManager {
  readonly silent: boolean;
  readonly log?: (...args: any) => void;
  readonly options: PackageManagerOptions;

  /** Get the name of the package manager */
  abstract readonly name: string;
  
  /** Get the executable binary of the package manager */
  abstract readonly bin: string;
  
  /** Get the lockfile for this package manager */
  abstract readonly lockFile: string;

  constructor(options?: PackageManagerOptions);

  runAsync(command: string[], options?: SpawnOptions): SpawnPromise<SpawnResult>;
  runBinAsync(command: string[], options?: SpawnOptions): SpawnPromise<SpawnResult>;
  versionAsync(): Promise<string>;
  getConfigAsync(key: string): Promise<string>;
  removeLockfileAsync(): Promise<void>;
  installAsync(flags?: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  uninstallAsync(): Promise<void>;
}

NPM Package Manager

Implementation for npm package manager with npm-specific optimizations.

class NpmPackageManager extends BasePackageManager {
  readonly name = 'npm';
  readonly bin = 'npm';
  readonly lockFile = 'package-lock.json';

  workspaceRoot(): NpmPackageManager | null;
  
  addAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  addDevAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult> | PendingSpawnPromise<SpawnResult>;
  addGlobalAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  
  removeAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  
  runBinAsync(command: string[], options?: SpawnOptions): SpawnPromise<SpawnResult>;
}

Usage Examples:

import { NpmPackageManager } from '@expo/package-manager';

const npm = new NpmPackageManager({ cwd: '/path/to/project' });

// Install dependencies
await npm.installAsync();

// Add packages with version specifications
await npm.addAsync(['express@^4.18.0', 'lodash']);

// Use npx to run binaries
await npm.runBinAsync(['typescript', '--version']);

Yarn Package Manager

Implementation for Yarn package manager with offline support and workspace detection.

class YarnPackageManager extends BasePackageManager {
  readonly name = 'yarn';
  readonly bin = 'yarnpkg';
  readonly lockFile = 'yarn.lock';

  workspaceRoot(): YarnPackageManager | null;
  
  installAsync(flags?: string[]): PendingSpawnPromise<SpawnResult>;
  addAsync(namesOrFlags?: string[]): PendingSpawnPromise<SpawnResult>;
  addDevAsync(namesOrFlags?: string[]): PendingSpawnPromise<SpawnResult>;
  addGlobalAsync(namesOrFlags?: string[]): PendingSpawnPromise<SpawnResult>;
  
  removeAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
}

Usage Examples:

import { YarnPackageManager } from '@expo/package-manager';

const yarn = new YarnPackageManager({ cwd: '/path/to/project' });

// Yarn automatically handles offline mode
await yarn.installAsync();

// Add development dependencies
await yarn.addDevAsync(['@types/node', 'typescript']);

// Global package management
await yarn.addGlobalAsync(['nodemon']);
await yarn.removeGlobalAsync(['old-global-package']);

PNPM Package Manager

Implementation for pnpm package manager with CI-specific optimizations.

class PnpmPackageManager extends BasePackageManager {
  readonly name = 'pnpm';
  readonly bin = 'pnpm';
  readonly lockFile = 'pnpm-lock.yaml';

  workspaceRoot(): PnpmPackageManager | null;
  
  installAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addDevAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addGlobalAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  
  removeAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
}

Usage Examples:

import { PnpmPackageManager } from '@expo/package-manager';

const pnpm = new PnpmPackageManager({ cwd: '/path/to/project' });

// In CI, automatically adds --no-frozen-lockfile if not specified
await pnpm.installAsync();

// Standard dependency management
await pnpm.addAsync(['fastify', 'zod']);
await pnpm.removeAsync(['unused-package']);

Bun Package Manager

Implementation for Bun package manager.

class BunPackageManager extends BasePackageManager {
  readonly name = 'bun';
  readonly bin = 'bun';
  readonly lockFile = 'bun.lockb';

  workspaceRoot(): BunPackageManager | null;
  
  installAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addDevAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  addGlobalAsync(namesOrFlags?: string[]): SpawnPromise<SpawnResult>;
  
  removeAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeDevAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
  removeGlobalAsync(namesOrFlags: string[]): SpawnPromise<SpawnResult>;
}

Usage Examples:

import { BunPackageManager } from '@expo/package-manager';

const bun = new BunPackageManager({ cwd: '/path/to/project' });

// Fast installation with Bun
await bun.installAsync();

// Add packages
await bun.addAsync(['hono', '@types/bun']);

// Development dependencies
await bun.addDevAsync(['bun-types']);

Common Usage Patterns

Workspace Management:

// Get workspace root manager
const rootManager = manager.workspaceRoot();
if (rootManager) {
  // Install at workspace root
  await rootManager.installAsync();
}

Configuration Access:

// Get package manager configuration
const registry = await manager.getConfigAsync('registry');
const version = await manager.versionAsync();

Cleanup Operations:

// Remove dependencies and clean up
await manager.removeAsync(['old-package']);
await manager.removeLockfileAsync();
await manager.uninstallAsync(); // Removes node_modules

Running Commands:

// Run package manager commands
await manager.runAsync(['audit', 'fix']);

// Run package binaries
await manager.runBinAsync(['eslint', 'src/']);

Package Manager Type Union

type NodePackageManager = 
  | NpmPackageManager 
  | PnpmPackageManager
  | YarnPackageManager
  | BunPackageManager;