npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cafeine-software/foxyfs

v1.0.0

Published

Wrappers around node:fs/promises — every operation checks its result before resolving.

Downloads

57

Readme


Table of contents


Installation

npm install foxyfs

API

writeFileSafe(path, content)

Writes content (UTF-8) to path, then verifies the file is readable and its content matches exactly what was written.

import { writeFileSafe } from 'foxyfs';

await writeFileSafe('/tmp/hello.txt', 'Hello world');

| Parameter | Type | Description | |-----------|----------|--------------------------| | path | String | Absolute or relative path| | content | String | UTF-8 content to write |

Throws Error("Unable to write file") if the write or verification fails.


fileExists(path)

Returns true if the path exists and is readable, false otherwise. Never throws.

import { fileExists } from 'foxyfs';

if (await fileExists('/tmp/config.json')) { /* ... */ }

Returns Promise<Boolean>


mkdirSafe(path, deleteIfExists?)

Creates a directory (and its parents) recursively. If the directory already exists and deleteIfExists is true, it is deleted before being recreated.

import { mkdirSafe } from 'foxyfs';

await mkdirSafe('/tmp/a/b/c');
await mkdirSafe('/tmp/output', true); // wipes and recreates if already present

| Parameter | Type | Default | Description | |------------------|-----------|---------|-----------------------------------------------| | path | String | — | Path of the directory to create | | deleteIfExists | Boolean | false | Delete the existing directory first if true |


deleteFileSafe(path)

Deletes a file or directory (recursively), then verifies it no longer exists.

import { deleteFileSafe } from 'foxyfs';

await deleteFileSafe('/tmp/old-dir');

Throws Error("Unable to delete file") if the path does not exist or deletion fails.


emptyFolderSafe(path)

Deletes all direct children of a directory without removing the directory itself, then verifies it is empty.

import { emptyFolderSafe } from 'foxyfs';

await emptyFolderSafe('/tmp/cache');

Throws if path is not a directory or if the emptying is incomplete.


isEmptySafe(path)

Returns true if a file has zero size, or if a directory contains no entries.

import { isEmptySafe } from 'foxyfs';

const empty = await isEmptySafe('/tmp/output');

Returns Promise<Boolean> Throws Error("Unable to check if path is empty") if the path does not exist.


isDirectory(path)

Returns true if the path points to a directory.

import { isDirectory } from 'foxyfs';

const isDir = await isDirectory('/tmp/output');

Returns Promise<Boolean> Throws if the path does not exist or is not accessible.


cpSafe(src, dest)

Copies a file or directory (recursively) from src to dest. The original is preserved.

import { cpSafe } from 'foxyfs';

await cpSafe('/tmp/source', '/tmp/backup');

Throws Error("Unable to copy file") if the source does not exist or the copy fails.


mvSafe(src, dest)

Moves a file or directory from src to dest. Verifies the destination exists and the source is gone afterwards.

import { mvSafe } from 'foxyfs';

await mvSafe('/tmp/draft.txt', '/tmp/final.txt');

Throws Error("Unable to move file") if the source does not exist or the move fails.


statSafe(path)

Returns the Stats object from node:fs for the given path, after verifying accessibility.

import { statSafe } from 'foxyfs';

const stats = await statSafe('/tmp/file.txt');
console.log(stats.size, stats.isFile());

Returns Promise<fs.Stats> Throws Error("Unable to stat file") if the path does not exist.


listFilesSafe(path)

Returns the list of entry names (files and subdirectories) inside a directory, non-recursive.

import { listFilesSafe } from 'foxyfs';

const entries = await listFilesSafe('/tmp/output');
// ['a.txt', 'b.txt', 'subdir']

Returns Promise<Array<String>> Throws if path is not a directory or does not exist.


Error handling

All functions throw enriched errors:

try {
    await deleteFileSafe('/no/such/path');
} catch (err) {
    console.log(err.message);       // "Unable to delete file"
    console.log(err.cause.message); // chained root cause
    console.log(err.data);          // { path: '/no/such/path' }
}

The data property contains the operation context (path, src/dest, etc.).

Tests

npm test

Uses the native node:test runner — no external test dependency.

Contributors

Quentin Lamamy

Support

Buy me a coffee

License

CC BY-SA 4.0