Skip to content

Commit 8332fa7

Browse files
authored
feat: add first-class Bun and Deno runtime support (#309)
## First-class Bun & Deno runtime support Until now, `@lazarv/react-server` has been a Node.js-first framework with experimental adapter-level support for alternative runtimes. This PR promotes **Bun** and **Deno** to fully supported, first-class runtimes — from project scaffolding all the way through development, production builds, and deployment. ### What changes for users **Zero-config runtime detection** — When you run `react-server build` or `react-server start` under Bun or Deno, the framework now automatically detects the runtime and applies the correct adapter. No manual `adapter: "bun"` or `adapter: "deno"` configuration is needed anymore (though explicit overrides and `--no-adapter` still work). **Scaffolding just works** — `create-react-server` now detects the runtime you're using at project creation time and automatically configures `package.json` scripts accordingly: - **Bun** projects get `bun --bun react-server ...` scripts and `trustedDependencies` - **Deno** projects get `deno run -A npm:@lazarv/react-server ...` scripts and a `deno.json` with `nodeModulesDir: "manual"` + `byonm` - **Node.js** projects continue to work exactly as before **Simplified production start** — Instead of requiring users to manually run `.bun/start.mjs` or `.deno/start.mjs`, the standard `react-server start` command now handles everything, including import map generation for Deno and proper process spawning for both runtimes. ### What changes under the hood - **Runtime-aware module loading** — New loader plugins (`lib/loader/bun.mjs` and `lib/loader/deno.mjs`) handle the differences in how each runtime resolves `@lazarv/react-server/dist/...` specifiers, manifest files, and prebuilt configs during production serving. - **Dev server rendering for Deno** — Since Deno doesn't support Node.js `worker_threads`, a new process-based rendering pipeline (`render-process.mjs`, `render-process-channel.mjs`, `render-process-spawn.mjs`) communicates over stdio, replacing the worker thread approach while keeping the same external API. - **Improved `sys.mjs` process shim** — The Deno process polyfill is now more robust (adds `on`/`off`/`once`/`stdout`/`stderr` stubs) and no longer overwrites the real `process` global when Deno's Node compat layer already provides one. ### New examples - **`examples/bun/`** — A complete Bun example with SSR, client-side hydration, and interactive counter - **`examples/deno/`** — A complete Deno example with the same feature set plus `react-server.deno.json` configuration ### Testing - **Docker-based integration tests** for `create-react-server` covering Node.js, Bun, and Deno — each runtime is tested in an isolated container to verify that scaffolded projects build and start correctly. - **Vitest snapshot tests** verifying the generated project structure for each runtime/preset combination. - **New CI workflow** (`.github/workflows/create-react-server.yml`) runs these tests automatically on push and PR. ### Documentation Updated the getting started guide and deployment docs (English and Japanese) to reflect that Deno is now fully supported, remove the "not supported yet" notices, and document automatic adapter detection along with simplified deployment commands.
1 parent 6173127 commit 8332fa7

102 files changed

Lines changed: 42150 additions & 573 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: create-react-server 🧪
2+
3+
env:
4+
NODE_OPTIONS: --max-old-space-size=6144
5+
6+
permissions: {}
7+
8+
on:
9+
pull_request:
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
changed:
18+
name: Get changed files 📂
19+
runs-on: ubuntu-latest
20+
outputs:
21+
all_changed_files: ${{ steps.changed-files.outputs.all_changed_files }}
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 50
28+
29+
- name: Get changed files
30+
id: changed-files
31+
uses: tj-actions/changed-files@v45
32+
with:
33+
files: |
34+
packages/create-react-server/**
35+
packages/react-server/**
36+
.github/workflows/create-react-server.yml
37+
38+
test-create:
39+
needs: changed
40+
if: contains(needs.changed.outputs.all_changed_files, 'packages/create-react-server') || contains(needs.changed.outputs.all_changed_files, 'packages/react-server') || contains(needs.changed.outputs.all_changed_files, '.github/workflows/create-react-server.yml')
41+
timeout-minutes: 60
42+
runs-on: ubuntu-latest
43+
strategy:
44+
matrix:
45+
include:
46+
- runtime: node
47+
pkg_mgr: npm
48+
- runtime: node
49+
pkg_mgr: pnpm
50+
- runtime: bun
51+
pkg_mgr: npm
52+
- runtime: bun
53+
pkg_mgr: pnpm
54+
- runtime: bun
55+
pkg_mgr: bun
56+
- runtime: deno
57+
pkg_mgr: npm
58+
- runtime: deno
59+
pkg_mgr: pnpm
60+
fail-fast: false
61+
62+
name: "Test create ${{ matrix.runtime }}/${{ matrix.pkg_mgr }} 🧪"
63+
steps:
64+
- name: Checkout
65+
uses: actions/checkout@v4
66+
67+
- uses: ./.github/workflows/actions/common-setup
68+
with:
69+
node_version: 20
70+
71+
- name: Test create-react-server (${{ matrix.runtime }}/${{ matrix.pkg_mgr }})
72+
working-directory: ./packages/create-react-server/test
73+
run: PKG_MGR=${{ matrix.pkg_mgr }} pnpm test:${{ matrix.runtime }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ deno.lock
1919
*.sqlite
2020
*.log
2121
.eslintcache
22+
.npm-cache

docs/src/pages/en/(pages)/deploy/adapters.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ You can use adapters to configure your app for different deployment environments
2626

2727
Add `adapter` entry to your `react-server.config.mjs` file. You can specify the name of a built-in adapter (`vercel`, `netlify`, `cloudflare`, `bun`, or `deno`) as a string, or use an external adapter package.
2828

29+
> **Note:** When running a production build with **Bun** or **Deno**, the corresponding adapter is automatically detected and used without any configuration. You can override this with an explicit `adapter` setting in your config or via `--adapter <name>` on the CLI. Use `--no-adapter` to disable auto-detection.
30+
2931
```mjs
3032
export default {
3133
adapter: 'vercel',

docs/src/pages/en/(pages)/deploy/bun.mdx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ curl -fsSL https://bun.sh/install | bash
2222

2323
No additional packages are needed - the adapter is built into `@lazarv/react-server`.
2424

25-
Then add the adapter to your `react-server.config.mjs` file:
25+
When you run a production build with Bun, the `bun` adapter is **automatically detected and used** — no configuration is needed. If you want to be explicit or need to pass options, you can add the adapter to your `react-server.config.mjs` file:
2626

2727
```mjs
2828
export default {
@@ -102,10 +102,16 @@ This produces a `.bun/` directory with the following structure:
102102
## Deploy
103103
</Link>
104104

105-
Start the production server directly:
105+
Start the production server using the CLI:
106106

107107
```sh
108-
bun .bun/start.mjs
108+
bun --bun react-server start
109+
```
110+
111+
Or run it directly without the framework installed:
112+
113+
```sh
114+
bun --bun .bun/start.mjs
109115
```
110116

111117
Or use the `--deploy` flag to build and immediately start:

docs/src/pages/en/(pages)/deploy/deno.mdx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ curl -fsSL https://deno.land/install.sh | sh
2222

2323
No additional packages are needed - the adapter is built into `@lazarv/react-server`.
2424

25-
Then add the adapter to your `react-server.config.mjs` file:
25+
When you run a production build with Deno, the `deno` adapter is **automatically detected and used** — no configuration is needed. If you want to be explicit or need to pass options, you can add the adapter to your `react-server.config.mjs` file:
2626

2727
```mjs
2828
export default {
@@ -102,10 +102,16 @@ This produces a `.deno/` directory with the following structure:
102102
## Deploy
103103
</Link>
104104

105-
Start the production server directly:
105+
Start the production server using the CLI:
106106

107107
```sh
108-
deno run --allow-net --allow-read --allow-env --allow-sys .deno/start.mjs
108+
deno run -A npm:@lazarv/react-server start
109+
```
110+
111+
Or run it directly without the framework installed:
112+
113+
```sh
114+
deno run --config .deno/deno.json --allow-net --allow-read --allow-env --allow-sys .deno/start.mjs
109115
```
110116

111117
Or use the `--deploy` flag to build and immediately start:

docs/src/pages/en/(pages)/guide/get-started.mdx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ or when using Bun as your JavaScript runtime, you don't need anything else, just
2727

2828
- [Bun](https://bun.sh) v1.2.9 or higher
2929

30-
> **Note:** Deno is not supported yet. Please check back later for updates.
30+
or when using Deno as your JavaScript runtime:
31+
32+
- [Deno](https://deno.com) v2.0 or higher
3133

3234
<Link name="install">
3335
## Install
@@ -62,9 +64,9 @@ bun add @lazarv/react-server
6264
</Tab>
6365

6466
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
65-
66-
> **Note:** Deno is not supported yet. Please check back later for updates.
67-
67+
```sh
68+
deno run -A npm:@lazarv/react-server
69+
```
6870
</Tab>
6971

7072
</Tabs>
@@ -114,9 +116,9 @@ bun --bun react-server ./App.jsx
114116
</Tab>
115117

116118
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
117-
118-
> **Note:** Deno is not supported yet. Please check back later for updates.
119-
119+
```sh
120+
deno run -A npm:@lazarv/react-server ./App.jsx
121+
```
120122
</Tab>
121123

122124
</Tabs>
@@ -127,7 +129,7 @@ bun --bun react-server ./App.jsx
127129
## Build
128130
</Link>
129131

130-
After you have developed your application, you can build it for production. This will create a `.react-server` folder with all files needed to run your application in production mode.
132+
After you have developed your application, you can build it for production. This will create a `.react-server` folder with all files needed to run your application in production mode. When using Bun or Deno, the corresponding adapter is automatically detected and used, producing a self-contained bundle in `.bun/` or `.deno/`. You can override the auto-detected adapter with `--adapter <name>` or disable it with `--no-adapter`.
131133

132134
<Tabs name="build">
133135

@@ -156,9 +158,9 @@ bun --bun react-server build ./App.jsx
156158
</Tab>
157159

158160
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
159-
160-
> **Note:** Deno is not supported yet. Please check back later for updates.
161-
161+
```sh
162+
deno run -A npm:@lazarv/react-server build ./App.jsx
163+
```
162164
</Tab>
163165

164166
</Tabs>
@@ -167,7 +169,7 @@ bun --bun react-server build ./App.jsx
167169
## Production mode
168170
</Link>
169171

170-
To start your application in production, just use the `start` command. This will start your application in production mode.
172+
To start your application in production, just use the `start` command. This will start your application in production mode. When using Bun or Deno, the start command runs the adapter's generated entry point directly.
171173

172174
<Tabs name="production-mode">
173175

@@ -196,14 +198,14 @@ bun --bun react-server start
196198
</Tab>
197199

198200
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
199-
200-
> **Note:** Deno is not supported yet. Please check back later for updates.
201-
201+
```sh
202+
deno run -A npm:@lazarv/react-server start
203+
```
202204
</Tab>
203205

204206
</Tabs>
205207

206-
> **Note:** if you don't want to install the `@lazarv/react-server` package and you just want to try out something quickly, you can use `npx` to run the `react-server` CLI. This way, it's not required to install anything else if you use JavaScript. It's enough to have a `.jsx` file with a React Server Component exported as default to run your application. Just run `npx @lazarv/react-server ./App.jsx` to start your application in development mode. When using Bun, you can use `bunx --bun @lazarv/react-server` to run the `react-server` CLI.
208+
> **Note:** if you don't want to install the `@lazarv/react-server` package and you just want to try out something quickly, you can use `npx` to run the `react-server` CLI. This way, it's not required to install anything else if you use JavaScript. It's enough to have a `.jsx` file with a React Server Component exported as default to run your application. Just run `npx @lazarv/react-server ./App.jsx` to start your application in development mode. When using Bun, you can use `bunx --bun @lazarv/react-server` to run the `react-server` CLI. When using Deno, you can use `deno run -A npm:@lazarv/react-server ./App.jsx` to start a development server.
207209
208210
<Link name="next-steps">
209211
## Next steps

docs/src/pages/en/(pages)/guide/quick-start.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ bunx --bun @lazarv/react-server ./App.jsx
4545
</Tab>
4646

4747
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
48-
49-
> **Note:** Deno is not supported yet. Please check back later for updates.
50-
48+
```sh
49+
deno run -A npm:@lazarv/react-server ./App.jsx
50+
```
5151
</Tab>
5252

5353
</Tabs>
@@ -83,9 +83,9 @@ bunx --bun @lazarv/create-react-server
8383
</Tab>
8484

8585
<Tab title={<><Deno className="w-4 max-h-4" />Deno</>}>
86-
87-
> **Note:** Deno is not supported yet. Please check back later for updates.
88-
86+
```sh
87+
deno run -A npm:@lazarv/create-react-server
88+
```
8989
</Tab>
9090

9191
</Tabs>

docs/src/pages/ja/(pages)/deploy/adapters.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import Link from "../../../../components/Link.jsx";
2626

2727
`react-server.config.mjs`ファイルに `adapter` エントリを追加します。ビルトインアダプタの名前(`vercel``netlify``cloudflare``bun`、または `deno`)を文字列で指定するか、外部アダプタパッケージを使用できます。
2828

29+
> **Note:** **Bun** または **Deno** でプロダクションビルドを実行すると、対応するアダプタが自動的に検出・使用されます。設定は不要です。明示的な `adapter` 設定またはCLIの `--adapter <name>` で上書きできます。自動検出を無効にするには `--no-adapter` を使用してください。
30+
2931
```mjs
3032
export default {
3133
adapter: 'vercel',

docs/src/pages/ja/(pages)/deploy/bun.mdx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ curl -fsSL https://bun.sh/install | bash
2222

2323
追加のパッケージは不要です — アダプタは `@lazarv/react-server` に組み込まれています。
2424

25-
次に`react-server.config.mjs` ファイルにアダプタを追加します:
25+
Bun でプロダクションビルドを実行すると、`bun` アダプタが**自動的に検出・使用されます** — 設定は不要です。明示的に指定したい場合やオプションを渡したい場合は`react-server.config.mjs` ファイルにアダプタを追加します:
2626

2727
```mjs
2828
export default {
@@ -102,10 +102,16 @@ pnpm react-server build [root]
102102
## デプロイ
103103
</Link>
104104

105-
本番サーバを直接起動します
105+
CLIを使用して本番サーバを起動します
106106

107107
```sh
108-
bun .bun/start.mjs
108+
bun --bun react-server start
109+
```
110+
111+
フレームワークなしで直接起動することもできます:
112+
113+
```sh
114+
bun --bun .bun/start.mjs
109115
```
110116

111117
または `--deploy` フラグを使用してビルドと即時起動を行います:

docs/src/pages/ja/(pages)/deploy/deno.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ curl -fsSL https://deno.land/install.sh | sh
2222

2323
追加のパッケージは不要です — アダプタは `@lazarv/react-server` に組み込まれています。
2424

25-
次に`react-server.config.mjs` ファイルにアダプタを追加します:
25+
Deno でプロダクションビルドを実行すると、`deno` アダプタが**自動的に検出・使用されます** — 設定は不要です。明示的に指定したい場合やオプションを渡したい場合は`react-server.config.mjs` ファイルにアダプタを追加します:
2626

2727
```mjs
2828
export default {

0 commit comments

Comments
 (0)