Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

BrowserFS v2.0.0-beta

BrowserFS is an in-browser file system that emulates the Node JS file system API and supports storing and retrieving files from various backends. BrowserFS also integrates nicely into the Emscripten file system.

Build status

Backends

BrowserFS is highly extensible, and ships with many filesystem backends:

  • HTTPRequest: Downloads files on-demand from a webserver via XMLHttpRequest or fetch.
  • LocalStorage: Stores files in the browser's localStorage.
  • HTML5FS: Stores files into the HTML5 FileSystem API.
  • IndexedDB: Stores files into the browser's IndexedDB object database.
  • Dropbox: Stores files into the user's Dropbox account.
  • InMemory: Stores files in-memory. Thus, it is a temporary file store that clears when the user navigates away.
  • ZipFS: Read-only zip file-backed FS. Lazily decompresses files as you access them.
  • IsoFS: Mount an .iso file into the file system.
    • Supports Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard.
  • WorkerFS: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
  • MountableFileSystem: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
  • OverlayFS: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
  • AsyncMirror: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
    • Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
  • FolderAdapter: Wraps a file system, and scopes all interactions to a subfolder of that file system.
  • Emscripten: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the BaseFileSystem class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the API documentation for BrowserFS.

Building

Prerequisites:

  • Node and NPM
  • Run yarn install (or npm install) to install local dependencies and build BrowserFS

A minified build can be found in dist/browserfs.min.js, and the unminified build can be found in dist/browserfs.js.

Custom builds:

If you want to build BrowserFS with a subset of the available backends, change src/core/backends.ts to include only the backends you require, and re-build.

Using

Using BrowserFS.configure(), you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

<scripttype="text/javascript" src="browserfs.min.js"></script><scripttype="text/javascript">// Installs globals onto window:// * Buffer// * require (monkey-patches if already defined)// * process// You can pass in an arbitrary object if you do not wish to pollute// the global namespace.BrowserFS.install(window);// Configures BrowserFS to use the LocalStorage file system.BrowserFS.configure({fs: "LocalStorage"},function(e){if(e){// An error happened!throwe;}// Otherwise, BrowserFS is ready-to-use!});</script>

Now, you can write code like this:

varfs=require('fs');fs.writeFile('/test.txt','Cool, I can do this in the browser!',function(err){fs.readFile('/test.txt',function(err,contents){console.log(contents.toString());});});

The following code mounts a zip file to /zip, in-memory storage to /tmp, and IndexedDB browser-local storage to /home:

// Note: This is the new fetch API in the browser. You can use XHR too.fetch('mydata.zip').then(function(response){returnresponse.arrayBuffer();}).then(function(zipData){varBuffer=BrowserFS.BFSRequire('buffer').Buffer;BrowserFS.configure({fs: "MountableFileSystem",options: {"/zip": {fs: "ZipFS",options: {// Wrap as Buffer object.zipData: Buffer.from(zipData)}},"/tmp": {fs: "InMemory"},"/home": {fs: "IndexedDB"}}},function(e){if(e){// An error occurred.throwe;}// Otherwise, BrowserFS is ready to use!});});

Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a script tag or bundle it with your favorite JavaScript module bundler.

You can also use BrowserFS to supply your application with fs, path, and buffer modules, as well as the Buffer and process globals. BrowserFS contains shim modules for fs, buffer, path, and process that you can use with Webpack and Browserify.

Webpack:

module.exports={resolve: {// Use our versions of Node modules.alias: {'fs': 'browserfs/dist/shims/fs.js','buffer': 'browserfs/dist/shims/buffer.js','path': 'browserfs/dist/shims/path.js','processGlobal': 'browserfs/dist/shims/process.js','bufferGlobal': 'browserfs/dist/shims/bufferGlobal.js','bfsGlobal': require.resolve('browserfs')}},// REQUIRED to avoid issue "Uncaught TypeError: BrowserFS.BFSRequire is not a function"// See: https://github.com/jvilk/BrowserFS/issues/201module: {noParse: /browserfs\.js/},plugins: [// Expose BrowserFS, process, and Buffer globals.// NOTE: If you intend to use BrowserFS in a script tag, you do not need// to expose a BrowserFS global.newwebpack.ProvidePlugin({BrowserFS: 'bfsGlobal',process: 'processGlobal',Buffer: 'bufferGlobal'})],// DISABLE Webpack's built-in process and Buffer polyfills!node: {process: false,Buffer: false}};

Browserify:

varbrowserfsPath=require.resolve('browserfs');varbrowserifyConfig={// Override Browserify's builtins for buffer/fs/path.builtins: Object.assign({},require('browserify/lib/builtins'),{"buffer": require.resolve('browserfs/dist/shims/buffer.js'),"fs": require.resolve("browserfs/dist/shims/fs.js"),"path": require.resolve("browserfs/dist/shims/path.js")}),insertGlobalVars: {// process, Buffer, and BrowserFS globals.// BrowserFS global is not required if you include browserfs.js// in a script tag."process": function(){return"require('browserfs/dist/shims/process.js')"},'Buffer': function(){return"require('buffer').Buffer"},"BrowserFS": function(){return"require('"+browserfsPath+"')"}}};

Using with Node

You can use BrowserFS with Node. Simply add browserfs as an NPM dependency, and require('browserfs'). The object returned from this action is the same BrowserFS global described above.

If you need BrowserFS to return Node Buffer objects (instead of objects that implement the same interface), simply require('browserfs/dist/node/index') instead.

Using with Emscripten

You can use any synchronous BrowserFS file systems with Emscripten! Persist particular folders in the Emscripten file system to localStorage, or enable Emscripten to synchronously download files from another folder as they are requested.

Include browserfs.min.js into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your Module's preRun array:

/** * Mounts a localStorage-backed file system into the /data folder of Emscripten's file system. */functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Note: Do NOT use BrowserFS.install(window) on a page with an Emscripten application! Emscripten will be tricked into thinking that it is running in Node JS.

If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropbox), you'll need to wrap it into an AsyncMirror file system first:

/** * Run this prior to starting your Emscripten module. * @param dropboxClient An authenticated DropboxJS client. */functionasyncSetup(dropboxClient,cb){// This wraps Dropbox in the AsyncMirror file system.// BrowserFS will download all of Dropbox into an// InMemory file system, and mirror operations to// the two to keep them in sync.BrowserFS.configure({fs: "AsyncMirror",options: {sync: {fs: "InMemory"},async: {fs: "Dropbox",options: {client: dropboxClient}}}},cb);}functionsetupBFS(){// Grab the BrowserFS Emscripten FS plugin.varBFS=newBrowserFS.EmscriptenFS();// Create the folder that we'll turn into a mount point.FS.createFolder(FS.root,'data',true,true);// Mount BFS's root folder into the '/data' folder.FS.mount(BFS,{root: '/'},'/data');}

Testing

To run unit tests, simply run npm test.

Citing

BrowserFS is a component of the Doppio and Browsix research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use BrowserFS in a project that leads to a publication, please cite the academic papers on Doppio and Browsix:

John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation (2014), pp. 508–518.

@inproceedings{VilkDoppio,
author = {John Vilk and Emery D. Berger},
title = {{Doppio: Breaking the Browser Language Barrier}},
booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
pages = {508--518},
year = {2014},
url = {http://doi.acm.org/10.1145/2594291.2594293},
doi = {10.1145/2594291.2594293}
}

Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems (2017), pp. 253–266.

@inproceedings{PowersBrowsix,
author = {Bobby Powers and John Vilk and Emery D. Berger},
title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
booktitle = {Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems},
pages = {253--266},
year = {2017},
url = {http://doi.acm.org/10.1145/3037697.3037727},
doi = {10.1145/3037697.3037727}
}

License

BrowserFS is licensed under the MIT License. See LICENSE for details.

About

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages