Open paperdave opened 4 days ago
@paperdave I just discovered this tracking issue and am really excited about it! I also saw react-server-dom-bun
mentioned there. I had started working on this as part of building https://github.com/bndkt/kotekan (which I did abandon in favor of another approach which still heavily involves Bun and which will be at least partially obsolete once the things mentioned in this issue land). I'm happy to transfer https://www.npmjs.com/package/react-server-dom-bun to you, just ping me on https://x.com/bndkt.
I'm happy to transfer [
react-server-dom-bun
] to you
Great. I had spotted this package existing and I was a little worried on the difficulty of getting the package. I don't fully know what the plan will be, but I think the react project itself publishes the -webpack
and -turbopack
versions of the react-server.
So far, I got server components to work using react-server-dom-webpack
using the browser builds of both server and target (so i could use renderToReadableStream
), but those have a dependency on __webpack_require__
. I currently work around this by just defining __webpack_require__
// TODO: Remove this after `react-server-dom-bun` is uploaded
globalThis.__webpack_require__ = (id: string) => {
if (side == "server" && config.separateSSRGraph && !id.startsWith("ssr:")) {
return loadModule("ssr:" + id, LoadModuleType.UserDynamic).exports;
} else {
return loadModule(id, LoadModuleType.UserDynamic).exports;
}
};
on the server, i noticed that react sort of just ignores the manifest when using the browser build. when using the node.js server build, it uses dynamic import
for that module, which works a bit better (but no readable stream api).
so the bun version would basically work the same, but i would probably hold off doing it for a little bit longer in case some more bundler changes happen and there is a more optimal way to write the integration.
With #14258 merged, Bake can finally be tried out in canary builds (usage guide at end of issue). However, it is missing many features and testing that make it currently unsuitible for production-grade applications.
Remember this list is not in order, and that not every item on this list is strictly a blocker. I will edit it as the plan changes.
Contributions are appreciated. Please join #bake in the Bun Discord for questions relating to the architecture of the Dev Server, as well as if you are trying it out as a user or framework author.
"use server"
.minifySyntax
is not allowed as affects DCE in an observable way)Request
input (currently, theRequest
object given to the framework entry point is fake)Accept
header. Concrete use case: picking between serialized RSC payload or HTML.client-only
andserver-only
packages as special-cased errors.separateSSRGraph: false
POST /render
to render a non-route server component.framework.serverEntryPoint
)Bun.wipDevServerExpectHugeBreakingChanges
to an integration inBun.serve
Bun.serve
is subpar, contains too much code, and users deserves a redesigned modal. (partially contributor friendly)DevServer
. Must not interfere with the ability to use the web-app "offline"bun install
is run and reload the specific node_modules folders it changes. This should not requirecmd+s
is too much text imo.bun build --watch
but no one has noticed???TODO: Repair live bindings
TODO: check if this local is immediately assigned require() if so, we will instrument it with hot module reloading.
(contributor friendly)module.hot
(webpack)import.meta.hot
(vite)IncrementalGraph
and rebuild direct dependents. In turn, that should place a directory watcher for when the file is restored.Cmd+R
is pressed, it must not serve a stale bundle. The design for this to be fast is already present, but bundle re-assembly is not yet implemented.<a>
tags. (contributor friendly)react-server-dom-webpack
, getreact-server-dom-bun
DevServer
lag behind. This is either due to VSCode buffering saves together, or the spam of the event loop causes websocket backpressure. I have not fully explored the options, but it is worth investigating if the bundling could be done on the watcher thread. If not, then a third thread is used. A mutex would be needed for the client-side asset files, but not for the server side code.import.meta.env
defines that we miss to match vite (contributor friendly)__webpack_require__
act likerequire
(looks easy but actually nontrivial)Bun
global. This restriction is being imposed so thatbun build --compile
can one day generate much smaller production binaries (e.g. someone not usingBun.build
/Bun.Transpiler
in their app can drop the entire bundler from the binary). Since Bake is new, we can add this restriction here but not in the runtime, and it is not a breaking change.Expr.Data.writeToHasher
is incomplete (contributor friendly)generation for 'bun:bake/client'
hot-module-reloading instrumentation for 'export { ... } from'
hot-module-reloading instrumentation for 'export * from'
non-framework provided entry-point
(will probably just never support this)support non-server components build
handle listen failure
I will update this as I think of more. These are just the steps that come to mind. Additionally, I will open another issue containing the plan for production builds, though I think some of this work waits on the API design.
Reliability
There are currently 3 unit tests in total for Bake. Given the size and scope of the dev server alone, much more testing and tooling is needed.
./test/bundler
--format=internal_kit_dev
), initial payload--react-fast-refresh
)--server-components
)bake.DevServer.IncrementalGraph
. Do this by exposing a JS binding for DevServer inbun:internal-for-testing
which can be initialized and controlled by abun:test
suite. Instead of relying on arbitrary timers and puppeteer (these has lead to e2e tests for--watch
being slow and flaky. also, puppeteer is not available on all platforms). The purpose of these tests are to ensure that the correct incremental bundles are generated. I imagine this will be a sub-project comparable toexpectBundled
.Performance
While I have done little testing on the performance, I am confident that large projects will show decent reloading speed, but there is significant cost placed on the first bundle task. I'm sure a lot of work can be done to profile and micro-optimize things, but here is a list of broader changes to the design:
BundleThread
IncrementalGraph
garbage collection (1) at all, (2) while a browser tab is focused and source files are unlikely to be savedIncrementalGraph
to disk, so that closing and re-opening the dev server does not have to rebundle anything. Care must be taken to not be vulnerable to cache poisoning. This might not compelling, especially on smaller projects where the total time to build all files is under a second. I am only listing this point because I realized it was easy to write.Open-ended performance tasks:
Informal Usage Guide
The following is from the message I sent in the #bake channel on the Bun Discord
Bun Bake is an experimental API for building full-stack client-server web applications (this is the "Framework API [SOON]" item that has been greyed out on our docs for over a year). Today, our hot-reloading development server in is experimental beta. The purpose of this beta is to find bugs and gather feedback to shape the final API (we are thinking of, but still designing, a
Bun.serve
integration)Bake provides first-class support for React server components, but using a generic interface that can be used by any framework.
To try Bake dev server today, upgrade to the latest canary build,
bun upgrade --canary
and create a file with:The built in
react-server-components
framework requires external dependencies, which can be installed withbun install