How ThreeNative fits together
See which parts ThreeNative provides, which parts your game owns and where each kind of code goes.
On this page
The layers
You build scenes with plain Three.js objects. defineGame connects them to rendering, the game
loop, input, asset loading, state and plugins.
The shared game lives in src/game.ts. It runs in the browser or in the ThreeNative native
runtime, which supplies the window, graphics surface and input for the device. Browser setup stays
in src/main.ts. Materials, lights, camera and effects are editable files in src/render/.
Who owns what
| Part | Provides | You decide |
|---|---|---|
| Your game | Scenes, characters, rules, assets and UI. | How the game looks, plays and responds. |
@threenative/core |
Startup, game loop, input, asset loading and state. | Scenes, controls, settings and game systems. |
| Plugins | Shared services such as Rapier physics and playtesting. | Which services to use and how gameplay reacts. |
| Native runtime | The window, graphics surface and device input. | Target platforms and platform integrations. |
| Build tools | Asset processing and app packaging. | Asset settings, app identity and release options. |
ThreeNative reports events and your code gives them meaning. The physics plugin detects that a body entered a trigger. Your scene decides whether that scores a point or opens a door.
From startup to a frame
At startup, plugins set up their services and the first scene loads. The scene's enter adds
objects. ThreeNative then runs gameplay updates at a fixed step and draws the scene.
Put gameplay rules in the update. Two hooks cover work that must run at a specific point:
ctx.afterPhysicsruns after physics writes body positions. Use it for a camera that follows a body.ctx.beforeRenderruns once before each world draw. Frames that show only the loading screen do not call it.
ctx.renderer is the ThreeNative renderer wrapper. If a library needs the Three.js renderer, use
ctx.renderer.raw. If an effect needs one backend, check ctx.renderer.kind first. It is
"webgpu" or "webgl2".
UI
The optional @threenative/ui package runs React HUDs, menus and debug panels over the scene. The
minimal template takes the other route and draws its HUD inside the scene.
A HUD reads game values with useGameState and sends intents with useUiIntent. An intent is a
named request, such as "restart", that the game decides how to handle. The same state and intent
flow works over a native game.
The native runtime draws the 3D world itself. A WebUI overlay uses the platform WebView for menus and HUDs. See Native runtime for supported platforms and UI requirements.
Your own systems
Start an enemy, weapon or inventory as a plain TypeScript class, kept with the scene that creates it. Write a plugin when a service must take part in startup, updates and cleanup across the whole game.
Check the API before you build animation, camera, input or asset tools. Keep code that uses the raw renderer or raw physics behind a check for the backend it needs.
To keep a game portable:
- Keep browser setup in the web entry, so the shared game can run natively.
- Use
ctx.input,ctx.assetsand the game loop for controls, loading and timing. - When a scene ends, remove its callbacks and free resources it created. Leave shared assets alone.
- Run the playtests on every platform you release.