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

opfs-enhanced

v1.0.4

Published

Enhanced file system operations for browsers using OPFS (Origin Private File System)

Readme

OPFS Enhanced 🗄️

A modern TypeScript library for browser-based file system operations using OPFS (Origin Private File System)

TypeScript Browser Support License

✨ Features

  • 🚀 Modern API: Built on the latest OPFS standard, providing powerful browser file system operations
  • 📁 Complete Functionality: Supports file reading/writing, directory operations, file copying/moving, and more
  • 🎯 TypeScript: Fully written in TypeScript with complete type support
  • 🛡️ Error Handling: Comprehensive error handling with user-friendly error messages
  • 🔧 Easy to Use: API designed similar to fs-extra, reducing learning curve
  • High Performance: Utilizes native browser OPFS API for excellent performance
  • 🌐 Browser Compatible: Supports OPFS functionality in modern browsers

🚀 Quick Start

Installation

npm install opfs-enhanced

Basic Usage

import { FileSystem } from 'opfs-enhanced';

// Write file
await FileSystem.writeFile('hello.txt', 'Hello, World!');

// Read file
const content = await FileSystem.readFile('hello.txt');
console.log(content); // 'Hello, World!'

// Create directory
await FileSystem.ensureDir('my-folder');

// List directory contents
const files = await FileSystem.readdir('my-folder');

// Copy file
await FileSystem.copy('hello.txt', 'my-folder/hello-copy.txt');

// Move file
await FileSystem.move('hello.txt', 'my-folder/hello.txt');

// JSON operations
const data = { name: 'File Vault', version: '1.0.0' };
await FileSystem.writeJson('package.json', data);
const json = await FileSystem.readJson('package.json');

Demo Application

A complete file manager web application is included in the examples/ directory to demonstrate the library's capabilities. To run the demo:

npm install
npm run dev

Then open http://localhost:3000 to see the file manager in action.

🏗️ Project Structure

opfs-enhanced/
├── src/                          # TypeScript source code
│   ├── index.ts                  # Main library entry point
│   ├── types.ts                  # Type definitions
│   ├── core/                     # Core functionality
│   │   └── filesystem.ts         # File system operations
│   └── utils/                    # Utility functions
│       ├── errors.ts             # Error handling
│       └── path.ts               # Path utilities
├── examples/                     # Demo applications
│   └── web/                      # Web file manager demo
│       ├── styles/               # Demo CSS files
│       └── scripts/              # Demo JavaScript files
├── tests/                        # Test files
├── doc/                          # Documentation
├── index.html                    # Demo application entry point
├── package.json                  # Project configuration
├── tsconfig.json                 # TypeScript configuration
├── vite.config.ts                # Vite build configuration
└── README.md                     # This file

📚 API Documentation

File Operations

writeFile(path: string, data: string | ArrayBuffer | Uint8Array, options?: WriteOptions): Promise<void>

Write content to a file.

// Write text file
await FileSystem.writeFile('note.txt', 'This is a note');

// Write binary file
const buffer = new Uint8Array([72, 101, 108, 108, 111]);
await FileSystem.writeFile('data.bin', buffer);

readFile(path: string, encoding?: string): Promise<string>

Read file content as string.

const content = await FileSystem.readFile('note.txt');

readFileBuffer(path: string): Promise<ArrayBuffer>

Read file content as ArrayBuffer.

const buffer = await FileSystem.readFileBuffer('data.bin');

exists(path: string): Promise<boolean>

Check if file or directory exists.

const fileExists = await FileSystem.exists('note.txt');

stat(path: string): Promise<OPFSStats>

Get file or directory statistics.

const stats = await FileSystem.stat('note.txt');
console.log(stats.size, stats.lastModified, stats.kind);

remove(path: string): Promise<void>

Delete file or directory.

await FileSystem.remove('note.txt');
await FileSystem.remove('my-folder'); // Recursively delete directory

Directory Operations

mkdir(path: string, options?: EnsureOptions): Promise<void>

Create directory.

await FileSystem.mkdir('new-folder');
await FileSystem.mkdir('deep/nested/folder', { recursive: true });

ensureDir(path: string): Promise<void>

Ensure directory exists, create if it doesn't.

await FileSystem.ensureDir('path/to/folder');

readdir(path: string): Promise<string[]>

List directory contents.

const files = await FileSystem.readdir('my-folder');
console.log(files); // ['file1.txt', 'file2.txt', 'subfolder']

File Copy and Move Operations

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

Copy file or directory.

// Copy file
await FileSystem.copy('source.txt', 'destination.txt');

// Copy directory
await FileSystem.copy('source-folder', 'dest-folder');

// Copy with options
await FileSystem.copy('source.txt', 'dest.txt', {
  overwrite: true,
  filter: (src, dest) => !src.endsWith('.tmp')
});

move(src: string, dest: string, options?: MoveOptions): Promise<void>

Move file or directory.

await FileSystem.move('old-name.txt', 'new-name.txt');
await FileSystem.move('folder', 'new-location/folder');

JSON Operations

readJson(path: string, options?: ReadJsonOptions): Promise<any>

Read JSON file.

const data = await FileSystem.readJson('config.json');

// With options
const data = await FileSystem.readJson('config.json', {
  throws: false, // Return null instead of throwing error when file doesn't exist
  reviver: (key, value) => key === 'date' ? new Date(value) : value
});

writeJson(path: string, data: any, options?: WriteJsonOptions): Promise<void>

Write JSON file.

const data = { name: 'example', values: [1, 2, 3] };
await FileSystem.writeJson('data.json', data);

// With options
await FileSystem.writeJson('data.json', data, {
  spaces: 4, // Number of spaces for indentation
  replacer: (key, value) => typeof value === 'bigint' ? value.toString() : value
});

Directory Traversal

walk(path: string, options?: WalkOptions): AsyncGenerator<FileInfo>

Recursively traverse directory.

// Traverse all files
for await (const file of FileSystem.walk('my-folder')) {
  console.log(file.path, file.kind, file.size);
}

// Traverse with options
for await (const item of FileSystem.walk('my-folder', {
  includeDirs: true, // Include directories
  maxDepth: 2, // Maximum depth
  filter: (path, info) => info.kind === 'file' && path.endsWith('.txt')
})) {
  console.log(item.path);
}

🔧 Advanced Usage

Error Handling

import { FileSystemError, FileSystemErrorCode } from 'opfs-enhanced';

try {
  await FileSystem.readFile('non-existent.txt');
} catch (error) {
  if (error instanceof FileSystemError) {
    switch (error.code) {
      case FileSystemErrorCode.FILE_NOT_FOUND:
        console.log('File not found');
        break;
      case FileSystemErrorCode.PERMISSION_DENIED:
        console.log('Permission denied');
        break;
      default:
        console.log('Other error:', error.message);
    }
  }
}

Path Operations

import { dirname, basename, extname, joinPath } from 'opfs-enhanced';

const filePath = 'documents/projects/readme.md';
console.log(dirname(filePath));   // 'documents/projects'
console.log(basename(filePath));  // 'readme.md'
console.log(extname(filePath));   // '.md'

const newPath = joinPath('assets', 'images', 'logo.png');
console.log(newPath); // 'assets/images/logo.png'

🎯 Use Cases

1. Local Data Storage

// Save user settings
const userSettings = {
  theme: 'dark',
  language: 'en-US',
  autoSave: true
};
await FileSystem.writeJson('settings.json', userSettings);

// Read user settings
const settings = await FileSystem.readJson('settings.json');

2. File Editor

// Save document
await FileSystem.writeFile('documents/my-doc.md', documentContent);

// Create project structure
await FileSystem.ensureDir('project/src');
await FileSystem.ensureDir('project/assets');
await FileSystem.writeFile('project/README.md', '# My Project');

3. Cache Management

// Cache data
const cacheData = { data: results, timestamp: Date.now() };
await FileSystem.writeJson('cache/api-results.json', cacheData);

// Clean expired cache
for await (const file of FileSystem.walk('cache')) {
  const stats = await FileSystem.stat(file.path);
  if (Date.now() - stats.lastModified > 24 * 60 * 60 * 1000) {
    await FileSystem.remove(file.path);
  }
}

4. Backup Tool

// Create backup
const backupFolder = `backup-${new Date().toISOString().split('T')[0]}`;
await FileSystem.ensureDir(backupFolder);
await FileSystem.copy('important-data', `${backupFolder}/important-data`);

🌐 Browser Support

| Browser | Version | Support | |---------|---------|---------| | Chrome | 86+ | ✅ Full | | Firefox | 111+ | ✅ Full | | Safari | 15.2+ | ✅ Full | | Edge | 86+ | ✅ Full |

Note: OPFS requires a secure context (HTTPS or localhost)

🚧 Limitations

  1. Browser Support: Requires modern browsers with OPFS support
  2. Secure Context: Must be used in HTTPS or localhost environment
  3. Storage Space: Limited by browser storage quota
  4. Cross-Domain: Data is stored per domain, cannot be accessed across domains

🧪 Development Guide

Project Setup

# Clone project
git clone <repository-url>
cd opfs-enhanced

# Install dependencies
npm install

# Development
npm run dev

# Build
npm run build

# Test
npm test

# Run demo
npm run preview

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Testing

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • OPFS API - For providing browser file system access
  • TypeScript - For excellent type safety
  • Vite - For fast development and building
  • Biome - For code formatting and linting
  • fs-extra - For API inspiration

🤝 Support

If you have any questions or need help, please:

  1. Check the documentation
  2. Search existing issues
  3. Create a new issue

Made with ❤️ by the File Vault team