New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

react-three-game

Package Overview
Dependencies
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-three-game

Batteries included React Three Fiber game engine

latest
npmnpm
Version
0.0.56
Version published
Maintainers
1
Created
Source

react-three-game

JSON-first 3D game engine. React Three Fiber + WebGPU + Rapier Physics.

npm i react-three-game @react-three/fiber @react-three/rapier three

Prefab Editor Architecture

Agent Skill

npx skills add https://github.com/prnthh/react-three-game-skill

Usage Modes

GameCanvas + PrefabRoot: Pure renderer for embedding prefab data in standard R3F applications. Minimal wrapper - just renders the prefab as Three.js objects. Requires manual <Physics> setup. Physics always active. Use this to integrate prefabs into larger R3F scenes.

PrefabEditor: Managed scene with editor UI and play/pause controls for physics. Full authoring tool for level design and prototyping. Includes canvas, physics, transform gizmos, and inspector. Physics only runs in play mode. Can pass R3F components as children.

Basic Usage

import { Physics } from '@react-three/rapier';
import { GameCanvas, PrefabRoot } from 'react-three-game';

<GameCanvas>
  <Physics>
    <PrefabRoot data={{
      root: {
        id: "scene",
        children: [
          {
            id: "ground",
            components: {
              transform: { type: "Transform", properties: { position: [0, 0, 0], rotation: [-1.57, 0, 0] } },
              geometry: { type: "Geometry", properties: { geometryType: "plane", args: [50, 50] } },
              material: { type: "Material", properties: { color: "#3a3" } },
              physics: { type: "Physics", properties: { type: "fixed" } }
            }
          },
          {
            id: "ball",
            components: {
              transform: { type: "Transform", properties: { position: [0, 5, 0] } },
              geometry: { type: "Geometry", properties: { geometryType: "sphere" } },
              material: { type: "Material", properties: { color: "#f66" } },
              physics: { type: "Physics", properties: { type: "dynamic" } }
            }
          }
        ]
      }
    }} />
  </Physics>
</GameCanvas>

GameObject Schema

interface GameObject {
  id: string;
  disabled?: boolean;
  components?: Record<string, { type: string; properties: any }>;
  children?: GameObject[];
}

Built-in Components

ComponentKey Properties
Transformposition, rotation, scale — all [x,y,z] arrays, rotation in radians
GeometrygeometryType: box/sphere/plane/cylinder, args: dimension array
Materialcolor, texture?, metalness?, roughness?
Physicstype: dynamic/fixed/kinematicPosition/kinematicVelocity, mass?, restitution? (bounciness), friction?, plus any Rapier props
Modelfilename (GLB/FBX path), instanced? for GPU batching
SpotLightcolor, intensity, angle, penumbra

Custom Components

import { Component, registerComponent, FieldRenderer, FieldDefinition } from 'react-three-game';
import { useFrame } from '@react-three/fiber';

const rotatorFields: FieldDefinition[] = [
  { name: 'speed', type: 'number', label: 'Speed', step: 0.1 },
  { name: 'axis', type: 'select', label: 'Axis', options: [
    { value: 'x', label: 'X' },
    { value: 'y', label: 'Y' },
    { value: 'z', label: 'Z' },
  ]},
];

const Rotator: Component = {
  name: 'Rotator',
  Editor: ({ component, onUpdate }) => (
    <FieldRenderer fields={rotatorFields} values={component.properties} onChange={onUpdate} />
  ),
  View: ({ properties, children }) => {
    const ref = useRef<Group>(null);
    useFrame((_, dt) => { ref.current!.rotation.y += dt * properties.speed });
    return <group ref={ref}>{children}</group>;
  },
  defaultProperties: { speed: 1, axis: 'y' }
};

registerComponent(Rotator); // before rendering PrefabEditor

Wrapper components accept children (animations, controllers). Leaf components don't (lights, particles).

Schema-Driven Field Types

The FieldRenderer component auto-generates editor UI from a field schema:

TypeDescriptionOptions
vector3X/Y/Z inputs with drag-to-scrubsnap?: number
numberNumeric inputmin?, max?, step?
stringText inputplaceholder?
colorColor picker + hex input
booleanCheckbox
selectDropdownoptions: { value, label }[]
customRender function for one-off UIrender: (props) => ReactNode
// Custom field example for complex one-off UI
{
  name: 'gradient',
  type: 'custom',
  label: 'Gradient',
  render: ({ value, onChange, values, onChangeMultiple }) => (
    <GradientPicker value={value} onChange={onChange} />
  ),
}

Prefab Editor

import { PrefabEditor } from 'react-three-game';

// Standalone editor
<PrefabEditor initialPrefab={sceneData} onPrefabChange={setSceneData} />

// With custom R3F components
<PrefabEditor initialPrefab={sceneData}>
  <CustomComponent />
</PrefabEditor>

Keys: Translate / Rotate / Scale. Drag tree nodes to reparent. Import/export JSON. Physics only runs in play mode.

Internals

  • Transforms: Local in JSON, world computed via matrix multiplication
  • Instancing: model.properties.instanced = true<Merged> + <InstancedRigidBodies>
  • Models: GLB/GLTF (Draco) and FBX auto-load from filename

Tree Utilities

import { findNode, updateNode, updateNodeById, deleteNode, cloneNode, exportGLBData } from 'react-three-game';

const node = findNode(root, nodeId);
const updated = updateNode(root, nodeId, n => ({ ...n, disabled: true }));  // or updateNodeById
const afterDelete = deleteNode(root, nodeId);
const cloned = cloneNode(node);
const glbData = await exportGLBData(sceneRoot);  // export scene to GLB ArrayBuffer

Development

npm run dev     # tsc --watch + docs site (localhost:3000)
npm run build   # → /dist
npm run release # build + publish
/src                 → library (published)
/docs                → Next.js demo site

React 19 · Three.js WebGPU · TypeScript 5 · Rapier WASM · MIT License

Manifest generation script

A small helper script is included to auto-generate asset manifests from the public folder. See docs/generate-manifests.sh.

  • What it does: Searches public/models for .glb/.fbx, public/textures for .jpg/.png, and public/sound for .mp3/.wav, then writes JSON arrays to:

    • public/models/manifest.json
    • public/textures/manifest.json
    • public/sound/manifest.json

    These manifest files are used to populate the Asset Viewer in the Editor.

  • How to run:

    • Make it executable (once):

      chmod +x docs/generate-manifests.sh
      
    • Run the script from the repo root (zsh/bash):

      ./docs/generate-manifests.sh
      

The script is intentionally simple and portable (uses find/sed). If you need different file types or output formatting, edit docs/generate-manifests.sh.

FAQs

Package last updated on 15 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts