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

factory-functions.mddocs/

Factory Functions

Core factory functions for creating and resolving package managers automatically based on project configuration and lockfiles.

Capabilities

Create For Project

Creates the appropriate package manager for a project by detecting lockfiles or using explicit configuration.

/**
 * Creates a Node package manager from the provided options.
 * If options are not provided, it will infer the package manager from lockfiles.
 * When no package manager is found, it falls back to npm.
 * 
 * @param projectRoot - The root directory of the project
 * @param options - Configuration options with optional package manager selection
 * @returns NodePackageManager instance appropriate for the project
 */
function createForProject(
  projectRoot: string,
  options?: NodePackageManagerForProject
): NodePackageManager;

type NodePackageManagerForProject = PackageManagerOptions & 
  Partial<Record<NodePackageManager['name'], boolean>>;

Usage Examples:

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

// Auto-detect from lockfiles
const manager = createForProject('/path/to/project');

// Force specific package manager
const npmManager = createForProject('/path/to/project', { npm: true });
const yarnManager = createForProject('/path/to/project', { yarn: true });

// With additional options
const silentManager = createForProject('/path/to/project', { 
  silent: true,
  log: console.debug 
});

Resolve Package Manager

Resolves the package manager used by a project by checking for lockfiles.

/**
 * Resolve the used node package manager for a project by checking the lockfile.
 * This also tries to resolve the workspace root, if its part of a monorepo.
 * Optionally, provide a preferred packager to only resolve that one specifically.
 * 
 * @param projectRoot - The root directory of the project
 * @param preferredManager - Optional preferred package manager to check for specifically
 * @returns Package manager name or null if none found
 */
function resolvePackageManager(
  projectRoot: string,
  preferredManager?: NodePackageManager['name']
): NodePackageManager['name'] | null;

Usage Examples:

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

// Detect any package manager
const detected = resolvePackageManager('/path/to/project');
// Returns 'npm', 'yarn', 'pnpm', 'bun', or null

// Check for specific package manager
const hasYarn = resolvePackageManager('/path/to/project', 'yarn');
// Returns 'yarn' if yarn.lock exists, null otherwise

Workspace Root Resolution

Resolves the workspace root directory for monorepo projects.

/**
 * Resolves the workspace root directory if the project is part of a monorepo
 * 
 * @param projectRoot - The current project directory
 * @returns Workspace root path or null if not in a workspace
 */
function resolveWorkspaceRoot(projectRoot: string): string | null;

Usage Examples:

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

const workspaceRoot = resolveWorkspaceRoot('/path/to/nested/project');
if (workspaceRoot) {
  console.log(`Part of workspace at: ${workspaceRoot}`);
  
  // Create manager for workspace root
  const rootManager = createForProject(workspaceRoot);
}

Resolution Order and Constants

Package managers are resolved in a specific order based on lockfile presence.

const RESOLUTION_ORDER: NodePackageManager['name'][] = ['bun', 'yarn', 'npm', 'pnpm'];

const NPM_LOCK_FILE = 'package-lock.json';
const YARN_LOCK_FILE = 'yarn.lock';
const PNPM_LOCK_FILE = 'pnpm-lock.yaml';
const BUN_LOCK_FILE = 'bun.lockb';
const BUN_TEXT_LOCK_FILE = 'bun.lock';

The resolution process:

  1. If preferredManager is specified, only check for that manager's lockfiles
  2. Otherwise, check lockfiles in RESOLUTION_ORDER: bun → yarn → npm → pnpm
  3. Return the first package manager whose lockfile is found
  4. Return null if no lockfiles are found

Usage Examples:

import { RESOLUTION_ORDER, BUN_LOCK_FILE } from '@expo/package-manager';

// Check resolution order
console.log('Checking in order:', RESOLUTION_ORDER);

// Check for specific lockfiles
import fs from 'fs';
import path from 'path';

const hasBunLock = fs.existsSync(path.join(projectRoot, BUN_LOCK_FILE));

docs

cocoapods-package-manager.md

factory-functions.md

index.md

node-package-managers.md

utilities-helpers.md

tile.json