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 πŸ™

Β© 2025 – Pkg Stats / Ryan Hefner

fsesm

v0.2.2

Published

πŸš€ A modern, lightweight utility library for working with the file system in ESM and TypeScript projects.

Downloads

338

Readme

FSESM πŸš€ - Modern FS Utilities for ESM & TypeScript Projects

NPM Version GitHub Stars License: MIT

A modern, lightweight utility library for working with the file system in ESM and TypeScript projects.


πŸ”Ή What is FSESM?

FSESM is a collection of utility functions designed to simplify file system operations in ESM (ECMAScript Modules) and TypeScript projects. It provides sugar-coated methods for common tasks like reading, writing, moving, and managing files and directories, while avoiding unnecessary dependencies and keeping your code clean.

With FSESM, you can:

  • Handle files and directories with ease.
  • Work with JSON and .env files seamlessly.
  • Ensure directories and files exist before operations.
  • Recursively list files or check file types.
  • Manage .env variables programmatically.

βœ… Modern.
πŸš€ Lightweight.
πŸ› οΈ TypeScript-first.


πŸš€ Quick Start

Install FSESM via npm:

npm install fsesm

πŸ” Key Features

1️⃣ File System Utilities

  • Ensure directories and files exist before operations.
  • Read, write, and update JSON files with ease.
  • Move, copy, and remove files/directories safely.
  • Recursively list files in a directory.

2️⃣ .env File Management

  • Read, write, and update .env files programmatically.
  • Find missing or empty .env keys.
  • Parse .env files into objects with automatic type conversion.

3️⃣ Advanced Utilities

  • Find files upwards from a directory (e.g., package.json or .env).
  • Simple glob-based file searching with support for .gitignore.
  • Symlink management with safety checks.

πŸ“¦ Installation

Install FSESM globally or locally:

npm install -g fsesm

Or add it to your project:

npm install fsesm

πŸ“‹ All Methods at a Glance

| Method | Description | Parameters | | --------------------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | ensureDir(dirPath) | Ensures a directory exists. Creates it recursively if missing. | dirPath: string | | ensureFile(filePath) | Ensures a file exists. Creates parent directories and an empty file if missing. | filePath: string | | readJson<T>(filePath) | Reads and parses a JSON file. Returns null if the file is missing or invalid. | filePath: string | | writeJson(filePath, data) | Writes an object to a JSON file. Creates parent directories if needed. | filePath: string, data: unknown | | updateJson<T>(filePath, updater) | Updates a JSON file using an async updater function. | filePath: string, updater: (data: T) => Promise<T> \| T | | outputFile(filePath, data) | Writes data to a file, ensuring parent directories exist. | filePath: string, data: string \| Buffer | | move(src, dest, overwrite) | Moves a file or directory. Handles cross-device moves by copying and deleting. | src: string, dest: string, overwrite: boolean = false | | copy(src, dest) | Copies a file or directory recursively. | src: string, dest: string | | remove(path) | Removes a file or directory recursively. | path: string | | pathExists(path) | Checks if a file or directory exists. | path: string | | ensureSymlink(src, dest, type) | Ensures a symbolic link exists at the destination. | src: string, dest: string, type?: "file" \| "dir" \| "junction" | | emptyDir(dirPath) | Empties a directory by removing its contents. Creates the directory if missing. | dirPath: string | | readFileSafe(filePath, encoding) | Reads a file safely. Returns null if the file doesn't exist. | filePath: string, encoding: BufferEncoding \| null = "utf-8" | | isDirectory(path) | Checks if a path is a directory. | path: string | | isFile(path) | Checks if a path is a file. | path: string | | listFiles(dirPath) | Recursively lists all files in a directory. | dirPath: string | | findPackageJson(options) | Finds the nearest package.json file. | options: { cwd?: string, maxDepth?: number } | | readPackageJson<T>(options or path) | Reads and parses the nearest package.json file. | options: { cwd?: string, maxDepth?: number } | | updatePackageJson<T>(updater, options) | Updates the nearest package.json file using an async updater function. | options: { cwd?: string, maxDepth?: number }, updater: UpdateJsonFunc<T> | | findEnvFile(fileName?, options) | Finds the nearest .env file. | options: { cwd?: string, maxDepth?: number } | | readEnvFile<T>(fileName?, options) | Reads and parses the nearest .env file. | options: { cwd?: string, maxDepth?: number } | | parseEnv<T>(data) | Parses a .env file content into an object. | data: string | | writeEnvVar(envPath, key, value, onlyIfEmpty) | Writes a key-value pair to a .env file. Updates if the key exists. | envPath: string, key: string, value: string, onlyIfEmpty: boolean = false | | getEmptyEnvKeys(envPath) | Finds empty or missing keys in a .env file. | envPath: string | | writeEnvRecord(envPath, record) | Writes a record of key-value pairs to a .env file. | envPath: string, record: Record<string, string> | | updateEnv<T>(envPath, updater) | Updates a .env file using an async updater function. | envPath: string, updater: UpdateJsonFunc<T> | | findFileUpwards(fileName, options) | Finds a file by searching upwards from a directory. | fileName: string, options: { cwd?: string, maxDepth?: number } | | find(patterns, options) | Finds files or folders matching glob patterns. | patterns: string \| string[], options: GlobOptions |


GlobOptions

| Option | Description | | ----------------------------- | ------------------------------------------------------------------------------------ | | cwd | The directory to start searching from. Default: process.cwd(). | | maxDepth | Maximum depth to search. Default: Infinity. | | ignore | Patterns to ignore. Can include negations (e.g., !**/node_modules/**). | | matchFilesWithoutExtensions | Whether to match files without extensions. Default: true. | | absolute | Whether to return absolute paths. Default: false. | | useGitignore | Whether to respect .gitignore files. Default: false. | | type | Type of items to search for: 'files', 'folders', or 'all'. Default: 'files'. |


πŸ› οΈ Methods & Examples

1️⃣ File System Utilities

ensureDir(dirPath: string): Promise<void>

Ensures a directory exists. Creates it recursively if it doesn't.

import { ensureDir } from "fsesm";

await ensureDir("./path/to/directory");

ensureFile(filePath: string): Promise<void>

Ensures a file exists. Creates parent directories and an empty file if missing.

import { ensureFile } from "fsesm";

await ensureFile("./path/to/file.txt");

readJson<T = unknown>(filePath: string): Promise<T | null>

Reads and parses a JSON file. Returns null if the file doesn't exist or has invalid JSON.

import { readJson } from "fsesm";

const data = await readJson<{ key: string }>("./path/to/file.json");

writeJson(filePath: string, data: unknown): Promise<void>

Writes an object to a JSON file. Creates parent directories if needed.

import { writeJson } from "fsesm";

await writeJson("./path/to/file.json", { key: "value" });

move(src: string, dest: string, overwrite = false): Promise<void>

Moves a file or directory. Handles cross-device moves by copying and deleting.

import { move } from "fsesm";

await move("./source/file.txt", "./destination/file.txt");

copy(src: string, dest: string): Promise<void>

Copies a file or directory recursively.

import { copy } from "fsesm";

await copy("./source/file.txt", "./destination/file.txt");

remove(path: string): Promise<void>

Removes a file or directory recursively.

import { remove } from "fsesm";

await remove("./path/to/delete");

2️⃣ .env File Management

readEnvFile<T = Record<string, any>>(options: FindEnvFileOptions): Promise<{ path: string; data: T } | null>

Reads and parses a .env file into an object.

import { readEnvFile } from "fsesm";

const env = await readEnvFile<{ API_KEY: string }>();

writeEnvVar(envPath: string, key: string, value: string, onlyIfEmpty = false): Promise<void>

Writes a key-value pair to a .env file. Updates the value if the key exists.

import { writeEnvVar } from "fsesm";

await writeEnvVar("./.env", "API_KEY", "your-api-key");

getEmptyEnvKeys(envPath: string): Promise<string[]>

Finds keys in a .env file that are empty or missing.

import { getEmptyEnvKeys } from "fsesm";

const missingKeys = await getEmptyEnvKeys("./.env");

3️⃣ Advanced Utilities

findFileUpwards(fileName: string, options: FindFileUpwardsOptions): Promise<string | null>

Finds a file by searching upwards from the current directory.

import { findFileUpwards } from "fsesm";

const packageJsonPath = await findFileUpwards("package.json");

find(patterns: string | string[], options: GlobOptions): Promise<string[]>

Finds files or folders matching glob patterns.

import { find } from "fsesm";

const files = await find("**/*.ts", { cwd: "./src" });

ensureSymlink(src: string, dest: string, type?: "file" | "dir" | "junction"): Promise<void>

Ensures a symbolic link exists at the destination.

import { ensureSymlink } from "fsesm";

await ensureSymlink("./source/file.txt", "./destination/link.txt");

πŸ” Why FSESM?

  • No unnecessary dependencies.
  • Fully typed for TypeScript.
  • Works seamlessly with ESM projects.
  • Handles edge cases gracefully.
  • Lightweight and fast.

πŸ“œ License

FSESM is licensed under the MIT License.
Β© 2025 Unbywyd.


πŸ”— Links

πŸ”Ή NPM: FSESM on NPM
πŸ”Ή GitHub: FSESM Repository
πŸ”Ή Issues: Report a bug


πŸš€ Simplify your file system operations with FSESM!

Need more features? Open an issue or contribute on GitHub! 😊