or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-find-up

Find a file or directory by walking up parent directories

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/find-up@7.0.x

To install, run

npx @tessl/cli install tessl/npm-find-up@7.0.0

index.mddocs/

find-up

Find a file or directory by walking up parent directories. This library provides a comprehensive set of functions for traversing filesystem hierarchies upward from a starting directory to locate files or directories by name, pattern, or custom matcher function.

Package Information

  • Package Name: find-up
  • Package Type: npm
  • Language: JavaScript/TypeScript (ESM)
  • Installation: npm install find-up

Core Imports

import { 
  findUp, 
  findUpSync, 
  findUpMultiple, 
  findUpMultipleSync, 
  findUpStop, 
  pathExists, 
  pathExistsSync, 
  type Match, 
  type Options 
} from "find-up";

For specific imports:

import { findUp } from "find-up";
import { pathExists } from "find-up";

Basic Usage

import path from 'node:path';
import { findUp, pathExists } from 'find-up';

// Find a single file by name
console.log(await findUp('package.json'));
//=> '/Users/sindresorhus/project/package.json'

// Find from multiple possible names
console.log(await findUp(['config.json', 'config.js']));
//=> '/Users/sindresorhus/project/config.js'

// Find using a custom matcher function
console.log(await findUp(async directory => {
  const hasPackageJson = await pathExists(path.join(directory, 'package.json'));
  return hasPackageJson && directory;
}, {type: 'directory'}));
//=> '/Users/sindresorhus/project'

Architecture

find-up is built around a simple but powerful directory traversal pattern with several key architectural components:

  • Traversal Engine: Core upward directory walking algorithm that starts from a given directory and moves up the filesystem hierarchy
  • Matcher System: Flexible matching system supporting both simple string/array patterns and custom matcher functions
  • Async/Sync Variants: Parallel implementations for both asynchronous and synchronous operations across all functions
  • Multiple Results: Support for both single-result (findUp) and multiple-result (findUpMultiple) search patterns
  • Search Control: Fine-grained control over search behavior with findUpStop symbol and configurable stopping points
  • Path Utilities: Integration with path-exists library for robust filesystem existence checking
  • Type Safety: Complete TypeScript integration with proper type inference and overload patterns

The library follows a consistent API pattern where each core function has both async and sync variants, and each supports both simple name-based matching and custom matcher function approaches.

Capabilities

Single File Finding

Find the first occurrence of a file or directory by walking up parent directories.

/**
 * Find a file or directory by walking up parent directories (async)
 * @param name - Name or array of names to search for
 * @param options - Search configuration options
 * @returns Promise resolving to the first path found or undefined
 */
function findUp(name: string | readonly string[], options?: Options): Promise<string | undefined>;

/**
 * Find a file or directory using a custom matcher function (async)
 * @param matcher - Function called for each directory in the search
 * @param options - Search configuration options
 * @returns Promise resolving to the first path found or undefined
 */
function findUp(matcher: (directory: string) => (Match | Promise<Match>), options?: Options): Promise<string | undefined>;

/**
 * Find a file or directory by walking up parent directories (sync)
 * @param name - Name or array of names to search for
 * @param options - Search configuration options
 * @returns The first path found or undefined
 */
function findUpSync(name: string | readonly string[], options?: Options): string | undefined;

/**
 * Find a file or directory using a custom matcher function (sync)
 * @param matcher - Function called for each directory in the search
 * @param options - Search configuration options
 * @returns The first path found or undefined
 */
function findUpSync(matcher: (directory: string) => Match, options?: Options): string | undefined;

Multiple File Finding

Find all occurrences of a file or directory by walking up parent directories.

/**
 * Find files or directories by walking up parent directories (async)
 * @param name - Name or array of names to search for
 * @param options - Search configuration options
 * @returns Promise resolving to array of all paths found
 */
function findUpMultiple(name: string | readonly string[], options?: Options): Promise<string[]>;

/**
 * Find files or directories using a custom matcher function (async)
 * @param matcher - Function called for each directory in the search
 * @param options - Search configuration options
 * @returns Promise resolving to array of all paths found
 */
function findUpMultiple(matcher: (directory: string) => (Match | Promise<Match>), options?: Options): Promise<string[]>;

/**
 * Find files or directories by walking up parent directories (sync)
 * @param name - Name or array of names to search for
 * @param options - Search configuration options
 * @returns Array of all paths found
 */
function findUpMultipleSync(name: string | readonly string[], options?: Options): string[];

/**
 * Find files or directories using a custom matcher function (sync)
 * @param matcher - Function called for each directory in the search
 * @param options - Search configuration options
 * @returns Array of all paths found
 */
function findUpMultipleSync(matcher: (directory: string) => Match, options?: Options): string[];

Path Existence Checking

Utility functions for checking if files or directories exist.

/**
 * Check if a path exists (async)
 * @param path - Path to check for existence
 * @returns Promise resolving to true if path exists, false otherwise
 */
function pathExists(path: string): Promise<boolean>;

/**
 * Check if a path exists (sync)
 * @param path - Path to check for existence
 * @returns True if path exists, false otherwise
 */
function pathExistsSync(path: string): boolean;

Search Control

Symbol for controlling search behavior in matcher functions.

/**
 * Symbol that can be returned by a matcher function to stop the search
 * and force findUp to immediately return undefined
 */
const findUpStop: unique symbol;

Types

/**
 * Possible return values from matcher functions
 */
type Match = string | typeof findUpStop | undefined;

/**
 * Base options from locate-path library
 */
interface LocatePathOptions {
  /** Directory to start the search from (default: process.cwd()) */
  readonly cwd?: URL | string;
  /** Type of path to match: 'file' or 'directory' (default: 'file') */
  readonly type?: 'file' | 'directory';
  /** Allow symbolic links to match if they point to the chosen path type (default: true) */
  readonly allowSymlinks?: boolean;
}

/**
 * Configuration options for find-up functions (extends locate-path options)
 */
type Options = {
  /** Directory path where the search halts if no matches are found (default: root directory) */
  readonly stopAt?: string;
} & LocatePathOptions;

Usage Examples

Finding Configuration Files

import { findUp } from 'find-up';

// Find the nearest package.json
const packagePath = await findUp('package.json');
console.log(packagePath);
//=> '/Users/sindresorhus/project/package.json'

// Find any of several config file types
const configPath = await findUp(['.eslintrc.js', '.eslintrc.json', '.eslintrc.yml']);
console.log(configPath);
//=> '/Users/sindresorhus/project/.eslintrc.json'

Using Custom Matcher Functions

import path from 'node:path';
import { findUp, pathExists, findUpStop } from 'find-up';

// Find a directory containing both package.json and src/
const projectRoot = await findUp(async directory => {
  const hasPackage = await pathExists(path.join(directory, 'package.json'));
  const hasSrc = await pathExists(path.join(directory, 'src'));
  return hasPackage && hasSrc ? directory : undefined;
}, { type: 'directory' });

// Stop search early for performance
const workspacePath = await findUp(directory => {
  return path.basename(directory) === 'work' ? findUpStop : 'workspace.json';
});

Finding Multiple Instances

import { findUpMultiple } from 'find-up';

// Find all package.json files up the directory tree
const allPackageFiles = await findUpMultiple('package.json');
console.log(allPackageFiles);
//=> [
//     '/Users/sindresorhus/project/packages/cli/package.json',
//     '/Users/sindresorhus/project/package.json'
//   ]

Synchronous Operations

import { findUpSync, pathExistsSync } from 'find-up';

// Synchronous file finding
const configPath = findUpSync('config.json');

// Synchronous path checking
const exists = pathExistsSync('/path/to/file.txt');

Advanced Configuration

import { findUp } from 'find-up';

// Start search from specific directory
const result = await findUp('target.txt', {
  cwd: '/Users/sindresorhus/deep/nested/path'
});

// Look for directories instead of files
const dirResult = await findUp('node_modules', {
  type: 'directory'
});

// Stop search at specific directory
const limitedResult = await findUp('file.txt', {
  stopAt: '/Users/sindresorhus'
});

// Disable symlink following
const noSymlinksResult = await findUp('file.txt', {
  allowSymlinks: false
});

Common Patterns

Project Root Detection

import { findUp } from 'find-up';

// Find project root by looking for common project indicators
const projectRoot = await findUp([
  'package.json',
  'cargo.toml', 
  'go.mod',
  '.git'
], { type: 'directory' });

Configuration Loading

import path from 'node:path';
import { findUp, pathExists } from 'find-up';

// Find and load the nearest configuration file
const configPath = await findUp(async directory => {
  const candidates = [
    path.join(directory, 'my-tool.config.js'),
    path.join(directory, 'my-tool.config.json'),
    path.join(directory, '.my-toolrc')
  ];
  
  for (const candidate of candidates) {
    if (await pathExists(candidate)) {
      return candidate;
    }
  }
  
  return undefined;
});

Performance Optimization

import { findUp, findUpStop } from 'find-up';

// Stop search early to avoid traversing the entire filesystem
const result = await findUp(directory => {
  // Stop if we've reached a system directory
  if (directory === '/usr' || directory === '/opt') {
    return findUpStop;
  }
  
  // Continue searching for our target
  return 'my-file.txt';
});