happy-opfs
v2.0.2
Published
A browser-compatible file system module based on OPFS, inspired by Deno fs APIs. Supports async/sync operations, streaming zip/unzip, and Result-based error handling.
Maintainers
Readme
happy-opfs
A browser file system module based on OPFS, providing Deno-style APIs.
Why happy-opfs
The standard OPFS API differs significantly from familiar path-based file system APIs like Node.js and Deno. This library bridges that gap by providing Deno-style APIs in the browser.
All async APIs return Result types (similar to Rust) for better error handling.
Installation
pnpm add happy-opfs
# or
npm install happy-opfs
# or
yarn add happy-opfs
# or via JSR
jsr add @happy-js/happy-opfs[!NOTE] This package depends on
@std/pathfrom JSR. Add this to your.npmrc:@jsr:registry=https://npm.jsr.io
Features
| Category | APIs |
|----------|------|
| Core | createFile, mkdir, readDir, readFile, writeFile, remove, stat |
| Extended | appendFile, copy, move, exists, emptyDir, readTextFile, readBlobFile, readJsonFile, writeJsonFile |
| Stream | readFile with { encoding: 'stream' }, openWritableFileStream |
| Temp | mkTemp, generateTempPath, pruneTemp, deleteTemp |
| Zip | zip, unzip, zipFromUrl, unzipFromUrl |
| Network | downloadFile, uploadFile |
| Sync | All core operations have sync versions (e.g., mkdirSync, readFileSync) via Web Workers. Use SyncChannel.connect, SyncChannel.listen, SyncChannel.attach, SyncChannel.isReady for setup |
Examples
Run examples locally:
pnpm run eg
# Open https://localhost:5173Quick Start
import { mkdir, writeFile, readTextFile, remove } from 'happy-opfs';
// Write and read files
await mkdir('/data');
await writeFile('/data/hello.txt', 'Hello, OPFS!');
(await readTextFile('/data/hello.txt')).inspect((content) => {
console.log(content); // 'Hello, OPFS!'
});
await remove('/data');See more examples in the examples/ directory:
- Basic Usage - File CRUD operations
- Download & Upload - Network operations with progress
- Zip Operations - Compress and extract files
- Stream Operations - Read and write files using streams
- Sync API - Synchronous operations via Worker
- Shared Messenger - Share sync messenger between contexts
Browser Compatibility
| Browser | Version | |---------|---------| | Chrome | 86+ | | Edge | 86+ | | Firefox | 111+ | | Safari | 15.2+ |
For detailed compatibility, see MDN - OPFS.
You can install OPFS Explorer to visually inspect the file system.
Migrating from 1.x to 2.x
Breaking Change 1: readFile default return type
In 1.x, readFile returned ArrayBuffer by default. In 2.x, it returns Uint8Array.
// 1.x - default returned ArrayBuffer
const result = await readFile('/path/to/file');
// 2.x - default returns Uint8Array
const result = await readFile('/path/to/file');
// Migration: use .buffer property to get ArrayBuffer if needed
const uint8Array = await readFile('/path/to/file');
const arrayBuffer = uint8Array.unwrap().buffer;Breaking Change 2: Removed readFileStream and writeFileStream
These deprecated APIs have been removed. Use the new alternatives:
// 1.x
const stream = await readFileStream('/path/to/file');
const writable = await writeFileStream('/path/to/file');
// 2.x
const stream = await readFile('/path/to/file', { encoding: 'stream' });
const writable = await openWritableFileStream('/path/to/file');Test Coverage
Coverage is collected using V8 provider in real browser environment.
src/sync/channel/listen.tsis excluded because it runs in Web Worker context where V8 cannot instrumentsrc/async/core/*.tshas branches running in Worker context (viacreateSyncAccessHandle), tested through mock tests
