Skip to content

JiangJie/happy-opfs

Repository files navigation

happy-opfs

License Build Status codecov NPM version NPM downloads JSR Version JSR Score

A browser file system module based on OPFS, providing Deno-style APIs.


中文 | API Documentation


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/path from 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:5173

Quick 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:

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.ts is excluded because it runs in Web Worker context where V8 cannot instrument
  • src/async/core/*.ts has branches running in Worker context (via createSyncAccessHandle), tested through mock tests

License

MIT

About

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.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors