# firost

> Async glob, read and write files

Latest version **5.11.0** (published 2026-07-29) · MIT license · 0 weekly downloads

## Install

```sh
npm install firost
pnpm add firost
yarn add firost
bun add firost
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 5.11.0 |
| Published | 2026-07-29 |
| First published | 2018-09-27 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=22.18.0 |
| Dependencies | 21 |
| Unpacked size | 83.2 KB |
| Known vulnerabilities | 0 (+2 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 9 |
| Author | Tim Carry <tim@pixelastic.com> |
| Maintainers | pixelastic |
| Keywords | shell, filesystem, copy, move, delete |

## Links

- npm: https://www.npmjs.com/package/firost
- Repository: https://github.com/pixelastic/firost
- Homepage: https://projects.pixelastic.com/firost/
- npm.io page: https://npm.io/package/firost

## Dependencies (21)

- [ora](https://npm.io/package/ora.md) 9.3.0
- [execa](https://npm.io/package/execa.md) 9.6.1
- [which](https://npm.io/package/which.md) 6.0.1
- [globby](https://npm.io/package/globby.md) 16.1.0
- [nanoid](https://npm.io/package/nanoid.md) 5.1.6
- [golgoth](https://npm.io/package/golgoth.md) 3.1.0
- [is-glob](https://npm.io/package/is-glob.md) 4.0.3
- [chokidar](https://npm.io/package/chokidar.md) 5.0.0
- [empathic](https://npm.io/package/empathic.md) 2.0.0
- [fs-extra](https://npm.io/package/fs-extra.md) 11.3.3
- [rev-hash](https://npm.io/package/rev-hash.md) 4.1.0
- [std-mocks](https://npm.io/package/std-mocks.md) 2.0.0
- [untildify](https://npm.io/package/untildify.md) 6.0.0
- [multimatch](https://npm.io/package/multimatch.md) 7.0.0
- [strip-ansi](https://npm.io/package/strip-ansi.md) 7.1.2
- [yoctocolors](https://npm.io/package/yoctocolors.md) 2.1.2
- [eventemitter2](https://npm.io/package/eventemitter2.md) 6.4.9
- [normalize-url](https://npm.io/package/normalize-url.md) 8.1.1
- [@inquirer/input](https://npm.io/package/@inquirer/input.md) 5.0.4
- [@inquirer/select](https://npm.io/package/@inquirer/select.md) 5.0.4
- [json-stable-stringify](https://npm.io/package/json-stable-stringify.md) 1.3.0

## Alternatives

- [unionfs](https://npm.io/package/unionfs.md) — 2.2M weekly downloads
- [path-starts-with](https://npm.io/package/path-starts-with.md) — 35.9K weekly downloads
- [redzip](https://npm.io/package/redzip.md) — 1.2K weekly downloads
- [vscode-anymatch](https://npm.io/package/vscode-anymatch.md) — 848 weekly downloads
- [@ledgerhq/coin-filecoin](https://npm.io/package/@ledgerhq/coin-filecoin.md) — 793 weekly downloads

## Recent versions

- 5.11.0 (latest) — 2026-07-29
- 5.10.1 — 2026-07-24
- 5.10.0 — 2026-07-23
- 5.9.1 — 2026-05-01
- 5.9.0 — 2026-05-01
- 5.8.0 — 2026-04-16
- 5.7.0 — 2026-02-27
- 5.6.1 — 2026-02-11
- 5.6.0 — 2026-02-11
- 5.5.2 — 2026-02-06
- 5.5.1 — 2026-01-27
- 5.5.0 — 2026-01-26
- 5.4.3 — 2026-01-15
- 5.4.2 — 2026-01-13
- 5.4.1 — 2026-01-13
- … 153 more at https://npm.io/package/firost/versions

## README

<!--
  This file was automatically generated by 'aberlaas readme' from .README.template.md
  DO NOT EDIT MANUALLY
-->
# > firost

Async glob, read and write files.

I was getting tired of having to write the same helpers and wrappers for
reading/writing files, so I packaged the best libraries and made an API that
works well with `async`/`await`.

## Filesystem methods

These methods help in finding, reading, moving and writing files on disk.

### `absolute(filepath)`

Converts any filepath to an absolute path, resolving `~/` to home.

```js
absolute('../path/to/file/oops/../.') // /absolute/path/to/file
absolute('~/.npmrc') // /home/tim/.npmrc
```

### `copy(source, destination)`

Copy file(s)

```js
await copy('index.html', './dist/index.html');
await copy('./foo/*.html', './dist');
```

### `download(url, path)`

Download a file to specific path on disk

```js
await download('http://www.example.com/file.jpg', './example.jpg');
```

### `emptyDir(path)`

Empty the content of a directory

```js
await emptyDir('./foo/bar');
```

### `exists(path)`

Check if a file/directory exists

```js
await exists('./foo/bar/file.ext');
```

### `gitRoot()`

Returns the path of the closest directory holding a .git folder.

```js
gitRoot(); // /home/tim/projects/firost
gitRoot('~/projects/aberlaas/lib/main.js'); // /home/tim/projects/aberlaas/
```

### `glob(pattern, options = {})`

Returns an array of filepaths matching the specified glob pattern.

It will return hidden files and directories by default, but you can override it
by passing `hiddenFiles: false` or `directories: false` to the `options`
argument.

```js
const paths = await glob(['./src/**/*.css', '!./src/**/_*.css']);
const noHiddenFiles = await glob(['./lib/**/*.js'], {
  hiddenFiles: false,
});
const noDirectories = await glob(['./lib'], { directories: false });
```

### `isDirectory(path)`

Checks if the given path is a directory

```js
if (await isDirectory('./dist')) {
  console.info('Website created');
}
```

### `isFile(path)`

Checks if the given path is a file

```js
if (await isFile('./package.json')) {
  console.info('File exists');
}
```

### `mkdirp(path)`

Creates a set of nested directories if they don't yet exist.

```js
await mkdirp('./dist/css');
```

### `move(source, destination)`

Move file(s)

```js
await move('index.html', 'index.back.html');
await move('./*.html', './dist');
```

### `packageRoot()`

Returns the path of the closest directory holding a package.json file.

```js
packageRoot(); // /home/tim/projects/firost
packageRoot('~/projects/aberlaas/lib/main.js'); // /home/tim/projects/aberlaas/
```


### `read(path)`

Returns the textual content of a file located at the specified filepath.

```js
const content = await read('./src/css/style.css');
```

### `readJson(path)`

Returns the content of a JSON file as a JavaScript object.

```js
const data = await readJson('./records.json');
```

### `readJsonUrl(url)`

Returns the content of a JSON URL as a JavaScript object.

```js
const data = await readJsonUrl('http://www.example.com/data.json');
```

### `remove(target)`

Remove file(s)

```js
await remove('index.back.html');
await remove('*.back.html');
```

### `urlToFilepath(url)`

Converts an URL into a filepath suitable for writing the file to disk.

```js
const filepath = urlToFilepath(
  'http://www.example.com/path/file.html?foo=bar'
);
// http/www.example.com/path/file_foo-bar.html

// Also works with relative utls
const filepath = urlToFilepath('path/file.html?foo=bar');
// path/file_foo-bar.html
```

### `watch(pattern, callback, {watcherName})`

Watch for file change, and run specified callback with path to changed files.

```js
function doSomething(filepath, type) {
  console.info(`File ${filepath} was just ${type}`);
}
const watcher = await watch(
  './path/to/files/*.jpg',
  doSomething,
  'my-watcher'
);

// To remove the watcher:
await unwatch('my-watch');
// or await unwatch(watcher);
// To remove all watchers:
await unwatchAll();
// To force wait until all watchers are executed
await waitForWatchers();
```

### `write(content, destination)`

Write content to a file on disk.

```js
await write('This is my content', './dist/content.txt');
```

### `writeJson(data, destination)`

Write data to a JSON file on disk. Keys will be ordered alphabetically, for
easier diffing of the file.

```js
const records = [
  { name: 'foo', value: 2 },
  { value: 3, name: 'bar' },
];
await writeJson(records, './records/records.json');
```

## Shell methods

These methods help abstracting some common CLI tasks

### `exit`

Stop the current process with specified `exitCode`. Similar to `process.exit`.

```js
exit(1);
```

### `consoleInfo`

Display an information message

```js
consoleInfo('Info');
// • Info
```

### `consoleWarn`

Display a warning message

```js
consoleWarn('Warning');
// ⚠ Warning
```

### `consoleError`

Display an error message

```js
consoleInfo('Error');
// ✘ Error
```

### `consoleSuccess`

Display an success message

```js
consoleSuccess('Success');
// ✔ Success
```

### `prompt(question)`

Interactively ask user a question

```js
const mood = await prompt('How do you feel?');
```

### `run(command)`

Run a shell command just like in the terminal, but also allows access to
`stdout`, `stderr` and exit `code`.

#### Options

| name     | default value | description                                                                                 |
| -------- | ------------- | ------------------------------------------------------------------------------------------- |
| `shell`  | `false`       | Set to `true` to enable shell-specific feature (like &&, >, etc)                            |
| `stdout` | `true`        | Set to false to silence stdout                                                              |
| `stderr` | `true`        | Set to false to silence stderr                                                              |
| `stdin`  | `false`       | Set to true to allow user to input keyboard keys. This sets `stdout` and `stderr` to `true` |

```javascript
const { stdout } = await run('echo foo'); // foo
const { stderr } = await run('>&2 echo bar', { shell: true }); // foo
try {
  await run('echo foo && exit 42');
} catch (err) {
  // err.code = 42
  // err.stdout = foo
}
```

### `spinner(max)`

Creates a spinner with optional max number of elements.

```js
const progress = spinner(10);

progress.tick('Doing task 1');
progress.success('All tasks done');
// or progress.failure('All tasks failed');
```

### `shell(command)`

_Deprecated. Use `run` instead, it if much more flexible_

Run the given command in a shell. Returns `stdout`, throws with `stderr` and
`exitCode`.

```js
try {
  const result = await shell('git checkout -b master');
  console.info('Created branch master');
} catch (err) {
  console.error(err.message);
  console.error(err.code);
}
```

### `sleep(delay)`

Wait for a specific number of milliseconds

```js
await sleep(100); // Wait for 100 ms
```

### `tmpDirectory()`

Returns a random temporary folder, optionally scoped.

```js
tmpDirectory(); // /tmp/{some-random-uuid}
tmpDirectory('firost/scope/'); // /tmp/firost/scope/{some-random-uuid}
```

### `which(command)`

Returns the path to an executable on the system. Returns `false` if none is
found.

```js
if (!(await which('convert'))) {
  console.info('You need to install ImageMagick');
}
```

## Utils

### `cache`

Shared singleton to used a proxy cache.

```js
cache.write('foo', 42);
cache.read('foo'); // 42
cache.has('foo'); // true
cache.has('nope'); // false

cache.write('key', { foo: ['one', 'two'], bar: { three: 3 } });
cache.read('key.foo'); // ['one', 'two'];
cache.read('key.bar.three'); // 3

cache.clear('key.foo');
cache.has('key.foo'); // false

cache.clearAll();
cache.has('key'); // false
```

### `captureOutput`

Silence all output of the specified code, and return it instead

```js
const actual = await captureOutput(async () => {
  console.info("This will not get displayed");
  await run('echo Test');
  await run('./no-existing-script.sh');
});
// actual.stdout: ["This will not get displayed", "Test"]
// actual.stderr: ["Command does not exist"]
```

### `error`

Returns an `Error` with both a `.code` and a `.message`

```js
throw error('E_ERROR', 'This failed');
```

### `normalizeUrl`

Normalize a URL

```js
normalizeUrl('http://www.there.com/index.html?sort=asc&name=firost');
// http://www.there.com/?name=firost&sort=asc
```

### `pulse`

Shared event emitter to listen and emit events

```js
pulse.on('custom', data => {
  console.info(data);
});
pulse.emit('custom', 'Hello');
// Hello
```

### `firostImpot(id)`

Alternative to the default dynamic `import()`. Pass `forceReload: true` as an option to
force reloading the latest version on disk, bypassing the singleton cache.

```js
const module = await firostImport('./path/to/module.js');
const updatedModule = await firostImport('./path/to/module.js', {
  forceReload: true,
});
```

### `uuid()`

Returns a unique ID that could be used in URL of filepaths.

```js
console.info(uuid());
// V1StGXR8_Z5jdHi6B-myT
```

---
_Source: https://npm.io/package/firost · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
