{"id":10811,"library":"escalade","title":"escalade: Ascend Parent Directories","description":"escalade is a minimalistic and performant utility designed for synchronously or asynchronously traversing up parent directories to locate a specific file or directory. It continuously executes a provided callback function for each directory in the ancestry chain until the callback returns a truthy value, at which point the absolute path to the found item is returned, or until the system root directory is reached. The current stable version is `3.2.0`, with releases occurring a few times a year for patches, minor features, and ecosystem compatibility updates (e.g., Deno support, TypeScript resolution fixes). Its primary differentiators are its extremely small footprint (183-210 bytes gzipped) and its clear separation into synchronous and asynchronous execution modes, catering to a wide range of Node.js and Deno environments. It strictly searches direct parent directories and does not explore sibling directories of parents.","status":"active","version":"3.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/lukeed/escalade","tags":["javascript","find","parent","parents","directory","search","walk","typescript"],"install":[{"cmd":"npm install escalade","lang":"bash","label":"npm"},{"cmd":"yarn add escalade","lang":"bash","label":"yarn"},{"cmd":"pnpm add escalade","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the primary (async) ES Module export. For CommonJS, use `require('escalade')`. Since v3.2.0, separate TypeScript definitions are provided for ESM and CJS.","wrong":"const escalade = require('escalade');","symbol":"escalade","correct":"import escalade from 'escalade';"},{"note":"To use the synchronous version, import from the specific subpath `'escalade/sync'`. This is available for both ES Modules and CommonJS (`require('escalade/sync')`).","wrong":"const escaladeSync = require('escalade'); // Wrong path\nimport escaladeSync from 'escalade'; // Not the sync version","symbol":"escalade (sync version)","correct":"import escaladeSync from 'escalade/sync';"},{"note":"This is the primary (async) CommonJS export. Ensure your environment supports `exports` map resolution or use an older Node.js version where CJS resolution was default.","wrong":"import escalade from 'escalade';","symbol":"escalade (CommonJS)","correct":"const escalade = require('escalade');"}],"quickstart":{"code":"import { join } from 'path';\nimport escalade from 'escalade';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = join(__filename, '..');\n\n// Assuming a file structure like:\n// project-root/\n//   package.json\n//   src/\n//     index.js\n//     features/\n//       my-feature.js\n\nconst startPath = join(__dirname, 'features', 'my-feature.js');\n\nconsole.log(`Starting search from: ${startPath}`);\n\nasync function findPackageJson() {\n  const pkgPath = await escalade(startPath, (dir, names) => {\n    console.log(`  Searching in: ${dir}`);\n    if (names.includes('package.json')) {\n      return 'package.json';\n    }\n  });\n\n  if (pkgPath) {\n    console.log(`Found package.json at: ${pkgPath}`);\n    const packageJson = await import(pkgPath, { assert: { type: 'json' } });\n    console.log(`Package name: ${packageJson.default.name}`);\n  } else {\n    console.log('package.json not found in parent directories.');\n  }\n}\n\nfindPackageJson().catch(console.error);","lang":"typescript","description":"This example demonstrates how to use the async `escalade` function to traverse parent directories from a given starting path to find the nearest `package.json` file. It then logs the path and the package name if found."},"warnings":[{"fix":"If you need to search sibling directories or a broader filesystem scope, a different utility or manual directory traversal logic is required.","message":"escalade strictly traverses direct parent directories and will not explore sibling directories of any parent. Its search scope is limited to the direct ancestral chain.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure your `tsconfig.json`'s `moduleResolution` and `module` options are correctly configured for your environment (e.g., `Node16` or `NodeNext`). This change primarily resolves issues rather than introducing new ones, but older tooling might need updates.","message":"In `v3.2.0`, separate TypeScript definitions for ESM and CommonJS were introduced. Previously, only ESM definitions were shipped, which could cause tool or resolution ambiguity in certain TypeScript configurations. While a fix, it might require adjustments for existing TypeScript users.","severity":"breaking","affected_versions":">=3.2.0"},{"fix":"Update to `escalade@3.1.1` or newer. Alternatively, avoid Node.js versions 13.0-13.6 if using older `escalade` versions with CommonJS `require()`.","message":"Users running Node.js versions 13.0 through 13.6 (inclusive) might have encountered issues with `require()` due to early, partial support of the `exports` map behavior in those specific Node.js releases. This was patched in `v3.1.1`.","severity":"gotcha","affected_versions":">=3.0.0 <3.1.1"},{"fix":"When importing from `escalade/sync`, remove any `await` keywords and handle the return value directly, as it is synchronous. For asynchronous operations, import from the default `'escalade'` path.","message":"The `escalade/sync` module is not Promise-based. Attempting to `await` its return value will result in a runtime error because the function does not return a Promise.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are importing the correct version of escalade. If you need asynchronous behavior, import from `'escalade'`. If you intend to use the synchronous version from `'escalade/sync'`, remove `await` keywords as it returns its value directly.","cause":"Attempting to use `await` or `.then()` on the synchronous `escalade/sync` function.","error":"TypeError: escalade(...).then is not a function"},{"fix":"Ensure your `tsconfig.json` has appropriate `moduleResolution` settings (e.g., `Node16` or `NodeNext`). If using `escalade@3.1.2`, ensure `nodenext` is configured. For `escalade@3.2.0` and newer, separate ESM/CJS type definitions are provided, which should resolve most ambiguity issues. Clear `node_modules` and reinstall if issue persists.","cause":"TypeScript compilation issue due to incorrect module resolution or outdated type definitions.","error":"TS2307: Cannot find module 'escalade' or its corresponding type declarations."},{"fix":"Verify your Node.js version is compatible (>=12.17.0 for stable `exports` support). Ensure bundlers or module loaders are configured to handle `exports` maps. Updating `escalade` to the latest version (`v3.1.1` fixed some specific Node 13.x issues) can also help.","cause":"Node.js or build tool failing to resolve the `escalade/sync` subpath export, often due to an environment not fully supporting `exports` maps.","error":"Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'escalade/sync' imported from ..."}],"ecosystem":"npm"}