React tunnel that renders content in fiber-tree order.
npm i fiber-tunnel
Requires React 19.2 or later. Supports Suspense and Activity.
import { Canvas } from "@react-three/fiber";
import { fiberTunnel } from "fiber-tunnel";
const overlay = fiberTunnel();
function Card({ name }: { name: string }) {
return (
<mesh>
<overlay.In>
<li>{name}</li>
</overlay.In>
</mesh>
);
}
function App() {
return (
<>
<ul>
<overlay.Out />
</ul>
<Canvas>
<Card name="Ace" />
<Card name="King" />
</Canvas>
</>
);
}
fiberTunnel() returns { In, Out }.
Create tunnels at module scope or in a component with useState.
Content inside an In renders as if the In were a plain wrapper;
its host output renders at the Out.
React events bubble from the Out.
SSR renders empty Outs until hydration.
Await act in tests: the Out suspends once on mount.
Mount only one Out per tunnel.
Wrap nested React roots in FiberAnchor.
Pass the anchor's bridge to ContextBridge to share the outer providers.
import { ContextBridge, FiberAnchor } from "fiber-tunnel";
function Scene({ children }: { children: ReactNode }) {
return (
<FiberAnchor>
{(bridge) => (
<Canvas>
<ContextBridge bridge={bridge}>{children}</ContextBridge>
</Canvas>
)}
</FiberAnchor>
);
}
fiberTunnel({ bridge: false }): content renders as a child of the Out.fiberTunnel({ isolate: true }): content errors and suspensions
surface at the Out.Inspired by tunnel-rat.