Get the first path that exists on disk of multiple paths
npx @tessl/cli install tessl/npm-locate-path@7.2.00
# locate-path
1
2
locate-path is a utility library that efficiently finds the first existing path from a collection of file or directory paths. It provides both asynchronous and synchronous APIs for checking path existence, with configurable options including concurrency control, path type filtering, symlink handling, and working directory specification.
3
4
## Package Information
5
6
- **Package Name**: locate-path
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES Modules)
9
- **Installation**: `npm install locate-path`
10
11
## Core Imports
12
13
```javascript
14
import { locatePath, locatePathSync } from "locate-path";
15
```
16
17
For CommonJS environments (not recommended as this is an ES module):
18
19
```javascript
20
const { locatePath, locatePathSync } = require("locate-path");
21
```
22
23
## Basic Usage
24
25
```javascript
26
import { locatePath, locatePathSync } from "locate-path";
27
28
// Async usage - find first existing file
29
const files = [
30
'config.json',
31
'config.yaml', // Only this one exists
32
'config.toml'
33
];
34
35
const found = await locatePath(files);
36
console.log(found); // => 'config.yaml'
37
38
// Sync usage
39
const foundSync = locatePathSync(files);
40
console.log(foundSync); // => 'config.yaml'
41
42
// With options - find directories with concurrency control
43
const dirs = ['node_modules', 'dist', 'src'];
44
const foundDir = await locatePath(dirs, {
45
type: 'directory',
46
concurrency: 2,
47
cwd: '/path/to/project'
48
});
49
```
50
51
## Capabilities
52
53
### Asynchronous Path Location
54
55
Asynchronously find the first existing path from multiple candidates with concurrent checking and configurable options.
56
57
```javascript { .api }
58
/**
59
* Get the first path that exists on disk of multiple paths
60
* @param paths - The paths to check (can be any iterable of strings)
61
* @param options - Configuration options
62
* @returns Promise resolving to first existing path or undefined if none exist
63
*/
64
function locatePath(
65
paths: Iterable<string>,
66
options?: AsyncOptions
67
): Promise<string | undefined>;
68
69
interface AsyncOptions {
70
/** Current working directory (default: process.cwd()) */
71
readonly cwd?: URL | string;
72
/** Type of path to match: 'file' or 'directory' (default: 'file') */
73
readonly type?: 'file' | 'directory';
74
/** Allow symbolic links to match if they point to the requested path type (default: true) */
75
readonly allowSymlinks?: boolean;
76
/** Number of concurrently pending promises (default: Infinity, minimum: 1) */
77
readonly concurrency?: number;
78
/** Preserve paths order when searching - disable to improve performance (default: true) */
79
readonly preserveOrder?: boolean;
80
}
81
```
82
83
**Usage Examples:**
84
85
```javascript
86
// Find first existing config file
87
const configPath = await locatePath([
88
'app.config.js',
89
'app.config.json',
90
'.apprc'
91
]);
92
93
// Find directories only, with limited concurrency
94
const srcDir = await locatePath(['src', 'lib', 'source'], {
95
type: 'directory',
96
concurrency: 1,
97
cwd: '/project/root'
98
});
99
100
// Disable symlinks and order preservation for performance
101
const dataFile = await locatePath(['data.json', 'data.yaml'], {
102
allowSymlinks: false,
103
preserveOrder: false
104
});
105
106
// Using URL for cwd
107
const found = await locatePath(['index.js'], {
108
cwd: new URL('file:///project/path/')
109
});
110
```
111
112
### Synchronous Path Location
113
114
Synchronously find the first existing path from multiple candidates with configurable options.
115
116
```javascript { .api }
117
/**
118
* Synchronously get the first path that exists on disk of multiple paths
119
* @param paths - The paths to check (can be any iterable of strings)
120
* @param options - Configuration options
121
* @returns First existing path or undefined if none exist
122
*/
123
function locatePathSync(
124
paths: Iterable<string>,
125
options?: Options
126
): string | undefined;
127
128
interface Options {
129
/** Current working directory (default: process.cwd()) */
130
readonly cwd?: URL | string;
131
/** Type of path to match: 'file' or 'directory' (default: 'file') */
132
readonly type?: 'file' | 'directory';
133
/** Allow symbolic links to match if they point to the requested path type (default: true) */
134
readonly allowSymlinks?: boolean;
135
}
136
```
137
138
**Usage Examples:**
139
140
```javascript
141
// Basic synchronous usage
142
const path = locatePathSync(['readme.md', 'README.md', 'readme.txt']);
143
144
// Find executable in different locations
145
const executable = locatePathSync(['./bin/app', '/usr/local/bin/app'], {
146
type: 'file',
147
allowSymlinks: true
148
});
149
150
// Check for project root markers
151
const projectRoot = locatePathSync(['package.json', 'pyproject.toml', 'Cargo.toml'], {
152
cwd: process.cwd(),
153
type: 'file'
154
});
155
```
156
157
## Error Handling
158
159
Both functions validate the `type` parameter and throw an `Error` if an invalid type is specified:
160
161
```javascript
162
// These will throw: Error: Invalid type specified: <invalid_type>
163
await locatePath(['file.txt'], { type: 'invalid' }); // throws
164
locatePathSync(['file.txt'], { type: 123 }); // throws
165
```
166
167
File system errors (permission denied, network issues, etc.) are handled gracefully - paths that cannot be accessed are treated as non-existent rather than throwing errors.
168
169
## Platform Considerations
170
171
- **Symbolic Links**: Behavior may differ between platforms. On Windows, some symlink tests are skipped.
172
- **Path Resolution**: All paths are resolved relative to the `cwd` option using Node.js `path.resolve()`.
173
- **URL Support**: Both `cwd` parameter accepts URL objects, which are converted to file paths using `fileURLToPath()`.
174
175
## Performance Notes
176
177
- **Concurrency**: The async version uses `p-locate` for concurrent path checking. Higher concurrency can improve performance when checking many paths.
178
- **Order Preservation**: Setting `preserveOrder: false` can improve performance by allowing the first successful check to return immediately.
179
- **Sync vs Async**: The synchronous version checks paths sequentially and may be faster for small path lists or when running in environments where async overhead is significant.