Skip to content

Experiment: SharedArrayBuffer filesystem #2384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 19 commits into
base: trunk
Choose a base branch
from

Conversation

brandonpayton
Copy link
Member

This is an experimental PR originally created by @adamziel.

Motivation for the change, related issues

🚧 EXPERIMENTAL DOODLING 🚧 DO NOT MERGE 🚧

An experimental shared filesystem to support running multiple Playground workers in the web browser. It uses SharedArrayBuffer for storage, which enables multiple workers to access the same underlying data.

What works:

  • Mounting a SharedArrayBuffer filesystem
  • Spawning multiple workers
  • Sharing the same SharedArrayBuffer between all the workers
  • Writing to an SQLite database in worker 1 and reading the results in worker 2
  • Running WordPress!

Testing instructions

Run this command:

bun packages/playground/remote/src/lib/sab_node_wp.ts

You should see the following output:

[SABFS] [MAIN] Booting WordPress
[SABFS] [MAIN] Mounting shared array buffers
[SABFS] [MAIN] Mounted shared array buffers
[SABFS] [MAIN] Booted WordPress
Extracted Title: My WordPress Website
[SABFS] [MAIN] Spawning worker 1...
[SABFS] [MAIN] Worker 1 booted
[SABFS] [MAIN] Spawning worker 2...
[SABFS] [MAIN] Worker 2 booted
[PHP] Getting post titles...
[PHP] Found 4 posts:
[PHP] - ID: 1, Title: Hello world!
[PHP] - ID: 2, Title: Sample Page
[PHP] - ID: 3, Title: Privacy Policy
[PHP] - ID: 4, Title: Navigation
[PHP] Finished getting post titles.


[MAIN] Worker 1: Inserting a new post...
[PHP] Inserting a new post...
[PHP] Successfully inserted post with ID: 5


[MAIN] Worker 2: Listing posts again to verify insertion...
[PHP] Getting post titles again...
[PHP] Found 5 posts:
[PHP] - ID: 1, Title: Hello world!
[PHP] - ID: 2, Title: Sample Page
[PHP] - ID: 3, Title: Privacy Policy
[PHP] - ID: 4, Title: Navigation
[PHP] - ID: 5, Title: My New Post from Worker 1
[PHP] Finished getting post titles again.

This means we've successfully booted WordPress in the main thread, started to child workers, inserted a post in the first one, and read it in the second one 🎉

Remaining work

  • Actually review and understand the Shared Array Buffer filesystem. It's all vibe coding and asking o3 to fix errors. I have no idea why and how it works 🙈
  • Ideally, store the metadata and file contents in the same SharedArrayBuffer.
  • Find a good test suite to run this on to confirm all the major filesystem features are operational and don't fail in nuanced ways.
  • Test OPFS journaling as it relies on Filesystem handling nuances.
  • Support .grow() when we run out of disk space to avoid pre-allocating too much memory.
  • Clean up the files, there's a lot of dev stuff going around.
  • Test the above scenario in the browser, not just in Bun.
  • Discuss what kind architecture would be useful for these workers and how would it relate to the PHPProcessManager that we use today.

Possible alternatives

  • WASMFS may potentially be solving the same problem. I'm not sure.

Related issues

Some thoughts I jotted down as I worked

SharedArrayBuffers challenges

SharedArrayBuffers are only available with these headers:

Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: credentialless

However, setting them breaks:

  • Loading images, videos, and other resources from other origins, e.g. gravatar.com.
  • Embedding Playground in other sites.

How can I still use SharedArrayBuffers while allowing images from other origins?

GPT suggested

Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: credentialless

As credentialless still gives you crossOriginIsolated === true and SharedArrayBuffer keep working. The browser simply strips cookies from “no‑cors” requests and lets the images through. That’s exactly what it was designed for. Chrome (≥ 96) and Edge support it; Firefox 122+ does, Safari still doesn’t support SAB anyway. Canvas will still be tainted, so if you need to read pixels you’re back to option 1 or 3.

cc @brandonpayton

@brandonpayton brandonpayton added [Type] Exploration An exploration that may or may not result in mergable code [Aspect] Filesystem labels Jul 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Aspect] Filesystem [Type] Exploration An exploration that may or may not result in mergable code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants