CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo--package-manager

A comprehensive cross-platform package management abstraction library that enables developers to programmatically install, manage, and find packages across multiple package managers including npm, yarn, pnpm, bun for Node.js projects, and CocoaPods for iOS projects.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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;

docs

cocoapods-package-manager.md

factory-functions.md

index.md

node-package-managers.md

utilities-helpers.md

tile.json