diff --git a/.github/workflows/create-react-server.yml b/.github/workflows/create-react-server.yml
index 0f52b534..3ff4b5c5 100644
--- a/.github/workflows/create-react-server.yml
+++ b/.github/workflows/create-react-server.yml
@@ -95,7 +95,7 @@ jobs:
test-results:
name: Test Results 📊
needs: test-create
- if: always()
+ if: always() && needs.test-create.result != 'skipped'
runs-on: ubuntu-latest
steps:
- name: Checkout
diff --git a/examples/react-three/App.jsx b/examples/react-three/App.jsx
new file mode 100644
index 00000000..e4af30a5
--- /dev/null
+++ b/examples/react-three/App.jsx
@@ -0,0 +1,37 @@
+import ThreeScene from "./ThreeScene";
+
+export default function App() {
+ return (
+
+
+
+
+ React Three Fiber + React Server
+
+
+
+
+
React Three Fiber + @lazarv/react-server
+
+
+ A rotating cube rendered with @react-three/fiber inside a React
+ Server Component tree.
+
+
+
+
+ );
+}
diff --git a/examples/react-three/ThreeScene.jsx b/examples/react-three/ThreeScene.jsx
new file mode 100644
index 00000000..06bfdada
--- /dev/null
+++ b/examples/react-three/ThreeScene.jsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { useRef } from "react";
+import { Canvas, useFrame } from "@react-three/fiber";
+
+function RotatingBox() {
+ const meshRef = useRef(null);
+
+ useFrame((_, delta) => {
+ if (meshRef.current) {
+ meshRef.current.rotation.x += delta * 0.5;
+ meshRef.current.rotation.y += delta * 0.8;
+ }
+ });
+
+ return (
+
+
+
+
+ );
+}
+
+export default function ThreeScene() {
+ return (
+
+ );
+}
diff --git a/examples/react-three/package.json b/examples/react-three/package.json
new file mode 100644
index 00000000..ef8ec0ae
--- /dev/null
+++ b/examples/react-three/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "@lazarv/react-server-example-react-three",
+ "private": true,
+ "description": "@lazarv/react-server React Three Fiber example application",
+ "keywords": [],
+ "license": "ISC",
+ "author": "",
+ "scripts": {
+ "dev": "react-server ./App.jsx",
+ "build": "react-server build ./App.jsx",
+ "start": "react-server start"
+ },
+ "dependencies": {
+ "@lazarv/react-server": "workspace:^",
+ "@react-three/fiber": "^9.5.0",
+ "three": "^0.171.0"
+ },
+ "devDependencies": {
+ "@types/three": "^0.171.0"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 461b131f..c1ec5548 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -482,7 +482,7 @@ importers:
version: 6.3.4
ts-jest:
specifier: ^29.1.0
- version: 29.2.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest@29.7.0(@types/node@20.17.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.11.21)(@types/node@20.17.11)(typescript@5.7.2)))(typescript@5.7.2)
+ version: 29.2.5(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest@29.7.0(@types/node@20.17.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.11.21)(@types/node@20.17.11)(typescript@5.7.2)))(typescript@5.7.2)
ts-loader:
specifier: ^9.4.3
version: 9.5.1(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.11.21))
@@ -621,6 +621,22 @@ importers:
specifier: ^15.6.6
version: 15.6.6(react@19.2.1)
+ examples/react-three:
+ dependencies:
+ '@lazarv/react-server':
+ specifier: workspace:^
+ version: link:../../packages/react-server
+ '@react-three/fiber':
+ specifier: ^9.5.0
+ version: 9.5.0(@types/react@19.2.2)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(three@0.171.0)
+ three:
+ specifier: ^0.171.0
+ version: 0.171.0
+ devDependencies:
+ '@types/three':
+ specifier: ^0.171.0
+ version: 0.171.0
+
examples/remote:
dependencies:
'@lazarv/react-server':
@@ -4097,6 +4113,31 @@ packages:
'@radix-ui/rect@1.1.1':
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+ '@react-three/fiber@9.5.0':
+ resolution: {integrity: sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==}
+ peerDependencies:
+ expo: '>=43.0'
+ expo-asset: '>=8.4'
+ expo-file-system: '>=11.0'
+ expo-gl: '>=11.0'
+ react: '>=19 <19.3'
+ react-dom: '>=19 <19.3'
+ react-native: '>=0.78'
+ three: '>=0.156'
+ peerDependenciesMeta:
+ expo:
+ optional: true
+ expo-asset:
+ optional: true
+ expo-file-system:
+ optional: true
+ expo-gl:
+ optional: true
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
'@remirror/core-constants@2.0.2':
resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
@@ -4952,6 +4993,9 @@ packages:
'@tsconfig/node16@1.0.4':
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+ '@tweenjs/tween.js@23.1.3':
+ resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
+
'@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
@@ -5140,6 +5184,11 @@ packages:
peerDependencies:
'@types/react': ^19.2.0
+ '@types/react-reconciler@0.28.9':
+ resolution: {integrity: sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==}
+ peerDependencies:
+ '@types/react': '*'
+
'@types/react-transition-group@4.4.11':
resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==}
@@ -5161,12 +5210,18 @@ packages:
'@types/stack-utils@2.0.3':
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
+ '@types/stats.js@0.17.4':
+ resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==}
+
'@types/superagent@8.1.9':
resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==}
'@types/supertest@6.0.2':
resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==}
+ '@types/three@0.171.0':
+ resolution: {integrity: sha512-oLuT1SAsT+CUg/wxUTFHo0K3NtJLnx9sJhZWQJp/0uXqFpzSk1hRHmvWvpaAWSfvx2db0lVKZ5/wV0I0isD2mQ==}
+
'@types/unist@2.0.10':
resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==}
@@ -5176,6 +5231,9 @@ packages:
'@types/use-sync-external-store@0.0.6':
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+ '@types/webxr@0.5.24':
+ resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==}
+
'@types/yargs-parser@21.0.3':
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
@@ -5369,6 +5427,9 @@ packages:
'@webassemblyjs/wast-printer@1.14.1':
resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
+ '@webgpu/types@0.1.69':
+ resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==}
+
'@wolfy1339/lru-cache@11.0.2-patch.1':
resolution: {integrity: sha512-BgYZfL2ADCXKOw2wJtkM3slhHotawWkgIRRxq4wEybnZQPjvAp71SPX35xepMykTw8gXlzWcWPTY31hlbnRsDA==}
engines: {node: 18 >=18.20 || 20 || >=22}
@@ -7601,6 +7662,11 @@ packages:
resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
engines: {node: '>=6'}
+ its-fine@2.0.0:
+ resolution: {integrity: sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==}
+ peerDependencies:
+ react: ^19.0.0
+
jackspeak@3.4.0:
resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
engines: {node: '>=14'}
@@ -8348,6 +8414,9 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ meshoptimizer@0.18.1:
+ resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==}
+
methods@1.1.2:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
@@ -9550,6 +9619,15 @@ packages:
react: '>=16.6.0'
react-dom: '>=16.6.0'
+ react-use-measure@2.1.7:
+ resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==}
+ peerDependencies:
+ react: '>=16.13'
+ react-dom: '>=16.13'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+
react@0.0.0-experimental-ab18f33d-20260220:
resolution: {integrity: sha512-hnphlgmXP0DIbbWz/c0mMfxFsb+qQ6gCMbE6IyvbGz55ay1DgfYKD0YtKfWUOs2cktp4LmDM5+5ewGw9LSfiCg==}
engines: {node: '>=0.10.0'}
@@ -10229,6 +10307,11 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ suspend-react@0.1.3:
+ resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==}
+ peerDependencies:
+ react: '>=17.0'
+
svg-parser@2.0.4:
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
@@ -10323,6 +10406,9 @@ packages:
thread-stream@2.7.0:
resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==}
+ three@0.171.0:
+ resolution: {integrity: sha512-Y/lAXPaKZPcEdkKjh0JOAHVv8OOnv/NDJqm0wjfCzyQmfKxV7zvkwsnBgPBKTzJHToSOhRGQAGbPJObT59B/PQ==}
+
three@0.183.1:
resolution: {integrity: sha512-Psv6bbd3d/M/01MT2zZ+VmD0Vj2dbWTNhfe4CuSg7w5TuW96M3NOyCVuh9SZQ05CpGmD7NEcJhZw4GVjhCYxfQ==}
@@ -11133,6 +11219,24 @@ packages:
zod@4.1.12:
resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==}
+ zustand@5.0.11:
+ resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@types/react': '>=18.0.0'
+ immer: '>=9.0.6'
+ react: '>=18.0.0'
+ use-sync-external-store: '>=1.2.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+ use-sync-external-store:
+ optional: true
+
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -11633,21 +11737,45 @@ snapshots:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
@@ -11658,16 +11786,34 @@ snapshots:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.26.10)':
dependencies:
'@babel/core': 7.26.10
@@ -11688,41 +11834,89 @@ snapshots:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.27.1
+ optional: true
+
'@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.26.10)':
dependencies:
'@babel/core': 7.26.10
@@ -14907,6 +15101,26 @@ snapshots:
'@radix-ui/rect@1.1.1': {}
+ '@react-three/fiber@9.5.0(@types/react@19.2.2)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(three@0.171.0)':
+ dependencies:
+ '@babel/runtime': 7.26.7
+ '@types/webxr': 0.5.24
+ base64-js: 1.5.1
+ buffer: 6.0.3
+ its-fine: 2.0.0(@types/react@19.2.2)(react@19.2.1)
+ react: 19.2.1
+ react-use-measure: 2.1.7(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
+ scheduler: 0.27.0
+ suspend-react: 0.1.3(react@19.2.1)
+ three: 0.171.0
+ use-sync-external-store: 1.6.0(react@19.2.1)
+ zustand: 5.0.11(@types/react@19.2.2)(react@19.2.1)(use-sync-external-store@1.6.0(react@19.2.1))
+ optionalDependencies:
+ react-dom: 19.2.1(react@19.2.1)
+ transitivePeerDependencies:
+ - '@types/react'
+ - immer
+
'@remirror/core-constants@2.0.2': {}
'@remix-run/router@1.17.0': {}
@@ -15624,6 +15838,8 @@ snapshots:
'@tsconfig/node16@1.0.4': {}
+ '@tweenjs/tween.js@23.1.3': {}
+
'@tybys/wasm-util@0.10.1':
dependencies:
tslib: 2.8.1
@@ -15837,6 +16053,10 @@ snapshots:
dependencies:
'@types/react': 19.2.2
+ '@types/react-reconciler@0.28.9(@types/react@19.2.2)':
+ dependencies:
+ '@types/react': 19.2.2
+
'@types/react-transition-group@4.4.11':
dependencies:
'@types/react': 19.2.2
@@ -15865,6 +16085,8 @@ snapshots:
'@types/stack-utils@2.0.3': {}
+ '@types/stats.js@0.17.4': {}
+
'@types/superagent@8.1.9':
dependencies:
'@types/cookiejar': 2.1.5
@@ -15877,12 +16099,23 @@ snapshots:
'@types/methods': 1.1.4
'@types/superagent': 8.1.9
+ '@types/three@0.171.0':
+ dependencies:
+ '@tweenjs/tween.js': 23.1.3
+ '@types/stats.js': 0.17.4
+ '@types/webxr': 0.5.24
+ '@webgpu/types': 0.1.69
+ fflate: 0.8.2
+ meshoptimizer: 0.18.1
+
'@types/unist@2.0.10': {}
'@types/unist@3.0.2': {}
'@types/use-sync-external-store@0.0.6': {}
+ '@types/webxr@0.5.24': {}
+
'@types/yargs-parser@21.0.3': {}
'@types/yargs@17.0.33':
@@ -16202,6 +16435,8 @@ snapshots:
'@webassemblyjs/ast': 1.14.1
'@xtuc/long': 4.2.2
+ '@webgpu/types@0.1.69': {}
+
'@wolfy1339/lru-cache@11.0.2-patch.1': {}
'@xtuc/ieee754@1.2.0': {}
@@ -16485,6 +16720,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ babel-jest@29.7.0(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ '@jest/transform': 29.7.0
+ '@types/babel__core': 7.20.5
+ babel-plugin-istanbul: 6.1.1
+ babel-preset-jest: 29.6.3(@babel/core@7.29.0)
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ slash: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
babel-plugin-istanbul@6.1.1:
dependencies:
'@babel/helper-plugin-utils': 7.27.1
@@ -16527,12 +16776,39 @@ snapshots:
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5)
+ babel-preset-current-node-syntax@1.1.0(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0)
+ '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.29.0)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0)
+ optional: true
+
babel-preset-jest@29.6.3(@babel/core@7.28.5):
dependencies:
'@babel/core': 7.28.5
babel-plugin-jest-hoist: 29.6.3
babel-preset-current-node-syntax: 1.1.0(@babel/core@7.28.5)
+ babel-preset-jest@29.6.3(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ babel-plugin-jest-hoist: 29.6.3
+ babel-preset-current-node-syntax: 1.1.0(@babel/core@7.29.0)
+ optional: true
+
bail@2.0.2: {}
balanced-match@1.0.2: {}
@@ -18679,6 +18955,13 @@ snapshots:
iterare@1.2.1: {}
+ its-fine@2.0.0(@types/react@19.2.2)(react@19.2.1):
+ dependencies:
+ '@types/react-reconciler': 0.28.9(@types/react@19.2.2)
+ react: 19.2.1
+ transitivePeerDependencies:
+ - '@types/react'
+
jackspeak@3.4.0:
dependencies:
'@isaacs/cliui': 8.0.2
@@ -19653,6 +19936,8 @@ snapshots:
merge2@1.4.1: {}
+ meshoptimizer@0.18.1: {}
+
methods@1.1.2: {}
micromark-core-commonmark@2.0.1:
@@ -21095,6 +21380,12 @@ snapshots:
react: 19.2.1
react-dom: 19.2.1(react@19.2.1)
+ react-use-measure@2.1.7(react-dom@19.2.1(react@19.2.1))(react@19.2.1):
+ dependencies:
+ react: 19.2.1
+ optionalDependencies:
+ react-dom: 19.2.1(react@19.2.1)
+
react@0.0.0-experimental-ab18f33d-20260220: {}
react@19.2.1: {}
@@ -22021,6 +22312,10 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ suspend-react@0.1.3(react@19.2.1):
+ dependencies:
+ react: 19.2.1
+
svg-parser@2.0.4: {}
symbol-observable@4.0.0: {}
@@ -22135,6 +22430,8 @@ snapshots:
dependencies:
real-require: 0.2.0
+ three@0.171.0: {}
+
three@0.183.1: {}
throttle-debounce@5.0.2: {}
@@ -22203,7 +22500,7 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.2.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest@29.7.0(@types/node@20.17.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.11.21)(@types/node@20.17.11)(typescript@5.7.2)))(typescript@5.7.2):
+ ts-jest@29.2.5(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest@29.7.0(@types/node@20.17.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.11.21)(@types/node@20.17.11)(typescript@5.7.2)))(typescript@5.7.2):
dependencies:
bs-logger: 0.2.6
ejs: 3.1.10
@@ -22217,10 +22514,10 @@ snapshots:
typescript: 5.7.2
yargs-parser: 21.1.1
optionalDependencies:
- '@babel/core': 7.28.5
+ '@babel/core': 7.29.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- babel-jest: 29.7.0(@babel/core@7.28.5)
+ babel-jest: 29.7.0(@babel/core@7.29.0)
ts-loader@9.5.1(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.11.21)):
dependencies:
@@ -22923,4 +23220,10 @@ snapshots:
zod@4.1.12: {}
+ zustand@5.0.11(@types/react@19.2.2)(react@19.2.1)(use-sync-external-store@1.6.0(react@19.2.1)):
+ optionalDependencies:
+ '@types/react': 19.2.2
+ react: 19.2.1
+ use-sync-external-store: 1.6.0(react@19.2.1)
+
zwitch@2.0.4: {}
diff --git a/test/__test__/apps/react-three.spec.mjs b/test/__test__/apps/react-three.spec.mjs
new file mode 100644
index 00000000..f7d6b017
--- /dev/null
+++ b/test/__test__/apps/react-three.spec.mjs
@@ -0,0 +1,21 @@
+import { join } from "node:path";
+
+import { hostname, page, server, waitForHydration } from "playground/utils";
+import { expect, test } from "vitest";
+
+process.chdir(join(process.cwd(), "../examples/react-three"));
+
+test("react-three load", async () => {
+ await server("./App.jsx");
+ await page.goto(hostname);
+ await page.waitForLoadState("networkidle");
+ await waitForHydration();
+
+ expect(await page.title()).toBe("React Three Fiber + React Server");
+ expect(await page.textContent("h1")).toContain("React Three Fiber");
+
+ // @react-three/fiber mounts a