A pure-JS, content-addressed, copy-on-write virtual filesystem for the browser, featuring: deduplication, filesystem universes (snapshots), events, and optional asynchronous sync.
jFS3 is a modern, lightweight filesystem engine designed for browser environments and offline-first applications.
It stores file data as immutable, hashed blocks in IndexedDB, keeps inode structures in RAM while synchronizing them back to IndexedDB, and provides advanced features such as copy-on-write, universes (snapshots), block-level deduplication, and an event-driven architecture.
All in ~10 kB minified and with zero dependencies.
All file data is chunked, hashed, and stored by content.
All modifications create new blocks while preserving old ones.
Identical blocks across all files, directories, universes are stored only once.
Universes are isolated copies of filesystem subtrees.
Example:
fs.cloneUniverse("/","@backup");// create snapshotfs.cloneUniverse("@backup","/");// restore snapshotIncludes events:
- change-path
- create-file
- change-file
- delete-file
- create-dir
- delete-dir
- read-file
- write-block
- write-inode
- read-inode
- delete-inode
- move
- copy
- create-tree
- delete-tree
- create-universe
- delete-universe
Includes send/receive frame encoding, block transfer, metadata merge, tombstones, and timestamp-based conflict resolution.
Example (with WebXDC):
constfs=newjFS3(2048,true)// blocksize: 2048, sync: true// add send (TX)fs.addTX(// called on given interval (when payload aviable)(frame)=>{window.webxdc.sendUpdate({payload:frame})},// set interval (default: 10s)window.webxdc.sendUpdateInterval||10000,// set max-frame-size (default: 128kB)window.webxdc.sendUpdateMaxSize||128000)// connect receive (RX)window.webxdc.setUpdateListener((update)=>fs.pushRX(update.payload));Works in browsers, PWAs, WebViews, offline apps, and extensions (~10 kB minified).
<scriptsrc="jFS3.js"></script>Or:
importjFS3from"./jFS3.js";constfs=newjFS3(4096);// Use blocksize: 4096 bytes// Run when Filesystem is readyfs.onready(async()=>{// Create directoriesfs.mkdir("/docs");// Writeawaitfs.writeFile("/docs/hello.txt","Hello World");// Readconstfile=awaitfs.readFile("/docs/hello.txt");console.log(awaitfile.text());// Create a snapshotfs.cloneUniverse("/","@u1");// Delete filefs.rm("/docs/hello.txt");// Restore snapshot to revive deleted filefs.cloneUniverse("@u1","/");});JSON-based inode structures containing type, blocks, timestamps, etc.
Immutable, hashed blocks stored under a "blocks" store.
When writing data, jFS3 only stores new blocks if the content is unique. Existing blocks are reused through hash-based deduplication.
Runs every 30 seconds to delete unreferenced blocks.
jFS3 is built around the concept of filesystem universes.
The root universe "/" represents the active filesystem, but additional universes (e.g. "@backup", "@u1") can be created for snapshots, branching, and isolated changes.
Also any path can be transferred into a subpath of another or even the same universe, producing an identical copy of that subtree.
Uses base64-encoded JSON frames for block + inode replication.
fs.mkdir(path)fs.rmdir(path)fs.listdir(path)fs.chdir(path)fs.getcwd()
fs.writeFile(path, data, blocksize?)fs.appendFile(path, data, blocksize?)fs.readFile(path)fs.rm(path)
fs.copy(src, dest)fs.move(src, dest)
fs.abspath(path)fs.relpath(path, target?)fs.join(root, path)fs.split(path)fs.splitext(path)
fs.metainfo(path)fs.quota(path?)
fs.listUniverses()fs.cloneUniverse(src, name)fs.deleteUniverse(name)fs.transfer(srcTree, destTree)fs.deleteTree(path)
fs.on(event, handler)fs.off(event, handler)fs.onready(func)
fs.addTX(sendFunction, interval, frameSize)fs.pushRX(frame)
- Client-side File-Explorer
- Offline-first editors (text, code, binary)
- WebXDC / DeltaChat apps
- P2P sync
- Versioning + snapshots
- Git-like branching in-browser
Issues and feature suggestions are welcome. Contributions are appreciated!