findup-sync is a utility that finds the first file matching a given pattern by recursively searching from a starting directory upward through parent directories until a match is found or the root directory is reached. It uses micromatch for powerful glob pattern matching and integrates with detect-file for enhanced file detection.
npm install findup-syncconst findup = require('findup-sync');Note: This package is CommonJS only and does not provide native ES module support.
const findup = require('findup-sync');
// Find package.json starting from current directory
const packagePath = findup('package.json');
// Find config files with glob patterns
const configPath = findup('*.config.{js,json}');
// Start searching from a specific directory
const filepath = findup('README.md', { cwd: '/some/project/path' });
// Case-insensitive search
const caseInsensitivePath = findup('readme.*', { nocase: true });
// Search for multiple patterns (returns first match)
const multiPattern = findup(['gulpfile.js', 'Gulpfile.js', 'gulpfile.babel.js']);The package implements an upward directory traversal algorithm:
cwd directory (or current working directory if not specified)Finds the first file matching a given pattern by searching upward through the directory tree from a starting point.
/**
* Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
* @param {string|string[]} patterns - Glob pattern(s) or file path(s) to match against
* @param {object} [options] - Options to pass to micromatch and configure search behavior
* @returns {string|null} Returns the absolute path to the first matching file, or null if no match found
* @throws {TypeError} When the first argument is not a string or array
*/
module.exports = function(patterns, options);Parameters:
patterns (string|string[]): Glob pattern(s) or file path(s) to match against. Can be:
'package.json''*.config.js' or '**/package.json'['gulpfile.js', 'Gulpfile.js']'config/app.json'options (object, optional): Configuration options
cwd (string): Starting directory for search (defaults to process.cwd())nocase (boolean): Case-insensitive matching when truematchBase (boolean): Match basename of files when trueReturn Value:
null if no matching file is foundError Handling:
TypeError if the first argument is not a string or arrayfs.readdirSync, continues search)null for invalid patterns or when no files matchUsage Examples:
const findup = require('findup-sync');
// Basic file search
const pkg = findup('package.json');
// Returns: "/path/to/project/package.json" or null
// Glob patterns
const config = findup('*.config.{js,json}');
// Matches: webpack.config.js, babel.config.json, etc.
// Multiple patterns (first match wins)
const gulp = findup(['gulpfile.js', 'Gulpfile.js', 'gulpfile.babel.js']);
// Custom starting directory
const readme = findup('README.*', { cwd: '/some/project/deep/nested/dir' });
// Case-insensitive search
const license = findup('license*', { nocase: true });
// Matches: LICENSE, License.txt, license.md
// Complex glob patterns
const nested = findup('**/test/fixtures/*.json');
// Exact path matching
const specific = findup('config/database.yml', { cwd: '/app/src' });
// Match basename only
const base = findup('package.json', { matchBase: true });
// Finds package.json at any depth
// Tilde expansion (home directory)
const home = findup('.*rc', { cwd: '~' });// Find configuration files for build tools
const webpackConfig = findup(['webpack.config.js', 'webpack.config.babel.js']);
const gulpfile = findup(['gulpfile.js', 'gulpfile.babel.js', 'Gulpfile.js']);
const gruntfile = findup(['Gruntfile.js', 'gruntfile.js']);
// Find project root by looking for package.json
const projectRoot = findup('package.json');
const rootDir = projectRoot ? require('path').dirname(projectRoot) : null;// Look for various config formats
const eslintConfig = findup([
'.eslintrc.js',
'.eslintrc.json',
'.eslintrc.yml',
'.eslintrc.yaml'
]);
// Find test configuration
const jestConfig = findup(['jest.config.js', 'jest.config.json']);
const mochaOpts = findup(['.mocharc.json', '.mocharc.yml', 'mocha.opts']);// Start from deep nested directory, find nearest package.json
const nearestPkg = findup('package.json', {
cwd: '/monorepo/packages/sub-package/src/components'
});
// Find workspace root (usually has workspaces field in package.json)
const workspaceRoot = findup('lerna.json') || findup('pnpm-workspace.yaml');