or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

directory-operations.mddirectory-walking.mdfilesystem-metadata.mdindex.mdpath-objects.mdpath-resolution.md
tile.json

tessl/npm-path-scurry

Extremely high performant utility for building tools that read the file system, minimizing filesystem and path string munging operations to the greatest degree possible

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/path-scurry@2.0.x

To install, run

npx @tessl/cli install tessl/npm-path-scurry@2.0.0

index.mddocs/

path-scurry

path-scurry is a high-performance utility for building tools that read the file system, designed to minimize filesystem operations and path string manipulations. It provides intelligent caching mechanisms, cross-platform path handling, and multiple interfaces including streaming, async/await, and traditional callback patterns for maximum flexibility and performance.

Package Information

  • Package Name: path-scurry
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install path-scurry

Core Imports

import { PathScurry, Path } from "path-scurry";

For CommonJS:

const { PathScurry, Path } = require("path-scurry");

Platform-specific imports:

import { PathScurryWin32, PathScurryPosix, PathScurryDarwin } from "path-scurry";
import { PathWin32, PathPosix } from "path-scurry";

Basic Usage

import { PathScurry } from "path-scurry";

// Create a path walker for the current directory
const pw = new PathScurry(process.cwd());

// Simple directory traversal
for await (const entry of pw) {
  if (entry.isFile() && entry.name.endsWith(".js")) {
    console.log(entry.fullpath());
  }
}

// Path resolution with caching
const resolved = pw.resolve("./src/index.ts");
console.log(resolved); // Fully resolved absolute path

// Directory reading
const children = await pw.readdir("./src");
console.log(children.map(child => child.name));

Architecture

Path-scurry is built around several key components:

  • PathScurry Classes: Main interface providing filesystem operations and path resolution with intelligent caching
  • Path Objects: Represent individual filesystem entries with lazy-loaded metadata and cached operations
  • Caching System: LRU caches for path resolution, directory contents, and filesystem metadata to minimize syscalls
  • Cross-Platform Support: Platform-specific implementations handling Windows UNC paths, drive letters, and POSIX paths
  • Multiple APIs: Traditional fs-like methods, streaming interfaces, async iterators, and callback patterns

Capabilities

Path Resolution and Navigation

Core path resolution functionality with intelligent caching, supporting both relative and absolute paths across platforms.

class PathScurry {
  constructor(cwd?: URL | string, opts?: PathScurryOpts);
  resolve(...paths: string[]): string;
  resolvePosix(...paths: string[]): string;
  relative(entry?: PathBase | string): string;
  relativePosix(entry?: PathBase | string): string;
  basename(entry?: PathBase | string): string;
  dirname(entry?: PathBase | string): string;
  depth(path?: Path | string): number;
  chdir(path: string | Path): void;
}

interface PathScurryOpts {
  nocase?: boolean;
  childrenCacheSize?: number;
  fs?: FSOption;
}

Path Resolution

Directory Operations

High-performance directory reading and traversal with caching and multiple output formats.

// Directory reading
readdir(): Promise<PathBase[]>;
readdir(opts: { withFileTypes: false }): Promise<string[]>;
readdir(entry: PathBase | string): Promise<PathBase[]>;
readdir(entry: PathBase | string, opts: { withFileTypes: false }): Promise<string[]>;

readdirSync(): PathBase[];
readdirSync(opts: { withFileTypes: false }): string[];
readdirSync(entry: PathBase | string): PathBase[];
readdirSync(entry: PathBase | string, opts: { withFileTypes: false }): string[];

Directory Operations

File System Metadata

Cached filesystem metadata operations including lstat, readlink, and realpath with error handling.

lstat(entry?: string | PathBase): Promise<PathBase | undefined>;
lstatSync(entry?: string | PathBase): PathBase | undefined;

readlink(entry?: string | PathBase): Promise<string | undefined>;
readlink(entry: string | PathBase, opt: { withFileTypes: true }): Promise<PathBase | undefined>;
readlinkSync(entry?: string | PathBase): string | undefined;
readlinkSync(entry: string | PathBase, opt: { withFileTypes: true }): PathBase | undefined;

realpath(entry?: string | PathBase): Promise<string | undefined>;
realpath(entry: string | PathBase, opt: { withFileTypes: true }): Promise<PathBase | undefined>;
realpathSync(entry?: string | PathBase): string | undefined;
realpathSync(entry: string | PathBase, opt: { withFileTypes: true }): PathBase | undefined;

File System Metadata

Directory Walking and Traversal

Multiple interfaces for directory tree traversal including async/await, streaming, and synchronous options with filtering and symlink following.

// Async array-based walking
walk(): Promise<PathBase[]>;
walk(opts: WalkOptions): Promise<PathBase[] | string[]>;
walk(entry: string | PathBase, opts?: WalkOptions): Promise<PathBase[] | string[]>;

walkSync(): PathBase[];
walkSync(opts: WalkOptions): PathBase[] | string[];
walkSync(entry: string | PathBase, opts?: WalkOptions): PathBase[] | string[];

// Streaming interfaces
stream(): Minipass<PathBase>;
stream(opts: WalkOptions): Minipass<PathBase | string>;
streamSync(): Minipass<PathBase>;

// Async iteration
iterate(): AsyncGenerator<PathBase, void, void>;
iterate(opts: WalkOptions): AsyncGenerator<PathBase | string, void, void>;
iterateSync(): Generator<PathBase, void, void>;

interface WalkOptions {
  withFileTypes?: boolean;
  follow?: boolean;
  filter?: (entry: PathBase) => boolean;
  walkFilter?: (entry: PathBase) => boolean;
}

Directory Walking

Path Objects

Individual filesystem entry objects with lazy-loaded metadata, type checking, and path manipulation methods.

abstract class PathBase implements Dirent {
  name: string;
  isCWD: boolean;
  readonly parentPath: string;
  readonly path: string; // deprecated

  // Path navigation
  resolve(path?: string): PathBase;
  relative(): string;
  relativePosix(): string;
  fullpath(): string;
  fullpathPosix(): string;
  depth(): number;

  // Type checking
  isFile(): boolean;
  isDirectory(): boolean;
  isSymbolicLink(): boolean;
  isUnknown(): boolean;
  isType(type: Type): boolean;
  getType(): Type;
  isNamed(name: string): boolean;

  // Filesystem operations
  readdir(): Promise<PathBase[]>;
  readdirSync(): PathBase[];
  lstat(): Promise<PathBase | undefined>;
  lstatSync(): PathBase | undefined;
  readlink(): Promise<PathBase | undefined>;
  readlinkSync(): PathBase | undefined;
  realpath(): Promise<PathBase | undefined>;
  realpathSync(): PathBase | undefined;
}

type Type = 'Unknown' | 'FIFO' | 'CharacterDevice' | 'Directory' | 
           'BlockDevice' | 'File' | 'SymbolicLink' | 'Socket';

Path Objects

Types

type Path = PathBase | InstanceType<typeof Path>;
type PathScurry = PathScurryBase | InstanceType<typeof PathScurry>;

// Internal types also exported
type Children = PathBase[] & { provisional: number };

interface PathOpts {
  fullpath?: string;
  relative?: string;
  relativePosix?: string;
  parent?: PathBase;
  fs?: FSOption;
}

interface FSOption {
  lstatSync?: (path: string) => Stats;
  readdir?: (path: string, options: { withFileTypes: true }, 
            cb: (er: NodeJS.ErrnoException | null, entries?: Dirent[]) => any) => void;
  readdirSync?: (path: string, options: { withFileTypes: true }) => Dirent[];
  readlinkSync?: (path: string) => string;
  realpathSync?: (path: string) => string;
  promises?: {
    lstat?: (path: string) => Promise<Stats>;
    readdir?: (path: string, options: { withFileTypes: true }) => Promise<Dirent[]>;
    readlink?: (path: string) => Promise<string>;
    realpath?: (path: string) => Promise<string>;
  };
}

// Internal cache classes (exported but advanced usage)
class ResolveCache extends LRUCache<string, string> {
  constructor();
}

class ChildrenCache extends LRUCache<PathBase, Children> {
  constructor(maxSize?: number);
}