r3f-physics
enzed/r3f-skills
Add Rapier physics simulation to React Three Fiber with rigid bodies, colliders, forces, and joints.
What is r3f-physics?
Integrates the Rapier physics engine into React Three Fiber scenes, enabling collision-driven movement, forces, and constraints. Use this for interactive 3D physics simulations; use animation guidance for purely visual motion without collision detection.
- Mount Rapier Physics with dynamic and fixed rigid bodies that respond to forces and gravity
- Apply impulses and forces to bodies, with control over momentum and continuous acceleration
- Define colliders (cuboid, trimesh, hull, compound shapes) with proper density and mass management
- Create joints (fixed, revolute, spherical, spring, rope) to connect bodies with local anchors and constraints
- Use sensors to detect intersection enter/exit events without contact response
- Manage kinematic bodies with setNextKinematicTranslation/Rotation or velocity setters for controlled motion
How to install r3f-physics
npx skills add https://github.com/enzed/r3f-skills --skill r3f-physics- React Three Fiber 9+ and React 19+ (or compatible older versions with Rapier 1)
- Rapier 2 package installed and WASM module available
- Canvas with lighting and Suspense boundary for async Physics loading
How to use r3f-physics
- 1.Install the skill and verify your Fiber, React, and Rapier versions match the target release
- 2.Wrap your scene content in a Physics component with a fixed timeStep (e.g., 1/60)
- 3.Create RigidBody components for dynamic objects, setting type, position, and colliders
- 4.Add CuboidCollider or other collider shapes with correct half-extent dimensions (not full dimensions)
- 5.Use useBeforePhysicsStep to apply forces or impulses aligned with simulation ticks
- 6.Test resting contact, collider alignment, and body behavior at different render frame rates
Use cases
- Interactive 3D scenes where objects fall, collide, and respond to clicks or forces
- Physics-based character controllers with proper grounding detection on stairs and slopes
- Stacked or compound objects that require stable contact and sleeping optimization
- Sensor-based triggers that detect when objects enter or exit regions without physical collision
- Constrained mechanisms like hinges, springs, or ropes connecting multiple bodies
- 3D web developers building interactive React Three Fiber applications
- Game developers prototyping physics-driven mechanics in WebGL
- Simulation creators needing stable, deterministic rigid-body dynamics
- Developers familiar with Rapier or other physics engines seeking React integration
r3f-physics FAQ
No. The physics world is authoritative; do not animate a simulated mesh's position in useFrame, as interpolation can overwrite the physics result. Instead, let the RigidBody handle transforms and use forces/impulses for movement.
An impulse is a one-time momentum change applied instantly. A force persists until reset; repeated addForce calls accumulate. Use impulses for discrete actions and forces for continuous effects managed per physics step.
Cuboid collider args are half-extents, while BoxGeometry args are full dimensions. Verify collider sizes and positions match your world scale using debug rendering, and ensure colliders={false} is set if you supply manual colliders.
Use setNextKinematicTranslation/Rotation for position-kinematic bodies or set linear/angular velocity for velocity-kinematic bodies. Avoid teleporting with setTranslation, which bypasses expected collision response.
Sensors report intersection enter/exit without physical contact response. Use sensor intersection events rather than ordinary collision events for trigger-like behavior.
Full instructions (SKILL.md)
Source of truth, from enzed/r3f-skills.
name: r3f-physics description: Add Rapier rigid bodies, colliders, forces, sensors, and joints to React Three Fiber. Use for collision-driven movement and simulation; use animation guidance for purely visual motion.
React Three Fiber physics
Check installed Fiber, React, and Rapier versions. Rapier 2 targets Fiber 9 / React 19; older projects need their compatible package line. Keep rendering and simulation ownership separate.
Falling and clickable body
Mount beneath Canvas with lighting. Physics loads WASM asynchronously; include Suspense. Cuboid collider arguments are half-extents, unlike BoxGeometry's full dimensions.
import { Suspense, useRef } from 'react'
import { CuboidCollider, Physics, RigidBody, type RapierRigidBody } from '@react-three/rapier'
function FallingBox() {
const body = useRef<RapierRigidBody>(null)
return (
<RigidBody ref={body} position={[0, 2, 0]} colliders="cuboid" restitution={0.2}>
<mesh name="physics-box" onClick={() => body.current?.applyImpulse({ x: 0, y: 3, z: 0 }, true)}>
<boxGeometry />
<meshStandardMaterial color="coral" />
</mesh>
</RigidBody>
)
}
export default function Example() {
return (
<Suspense fallback={null}>
<Physics timeStep={1 / 60}>
<FallingBox />
<RigidBody type="fixed" colliders={false}>
<CuboidCollider args={[4, 0.25, 4]} position={[0, -0.25, 0]} />
<mesh position={[0, -0.25, 0]}>
<boxGeometry args={[8, 0.5, 8]} />
<meshStandardMaterial color="slategray" />
</mesh>
</RigidBody>
</Physics>
</Suspense>
)
}
Bodies and colliders
- Dynamic bodies respond to forces. Fixed bodies represent static surfaces. Position-kinematic bodies use
setNextKinematicTranslation/Rotation; velocity-kinematic bodies use linear/angular velocity setters. - Set initial transforms on RigidBody. Do not animate a simulated mesh's position in
useFrame; the physics world remains authoritative and interpolation can overwrite it. - Prefer simple colliders or compound convex shapes. Use trimesh mainly for static concave environments; a hull closes holes and cannot preserve arbitrary concavity.
- Set
colliders={false}when supplying complete manual colliders, otherwise automatic colliders may be added as well. Collider sizes/transforms must match world scale; use debug rendering to inspect them. - Choose collider density/mass consistently and avoid accidental duplicate mass from overlapping auto/manual colliders.
- For many repeated bodies, InstancedRigidBodies reduces rendering overhead, not the cost of simulating each body. Keep instance keys/transforms stable.
Forces and simulation time
- An impulse is a one-time momentum change. A force persists until reset; repeated
addForcecalls accumulate. Do not add the same continuous force every render frame without an explicit force-management strategy. - Use
useBeforePhysicsStepfor input/forces that must align with simulation ticks. If a controller owns all user forces on a body, it can reset and reapply them per tick; coordinate with other force sources before resetting. - Kinematic targets should advance on physics steps. Teleporting with
setTranslationis different from kinematic movement and can bypass expected collision response. - Prefer a fixed timestep for stable behavior.
timeStep="vary"trades predictability for variable stepping; multiplying values by render delta does not make the physics deterministic. - For demand rendering, use
Physics updateLoop="independent"so active bodies can request renders. A sleeping world should not force unnecessary rendering. - Let bodies sleep; explicitly wake them when applying actions that need it. Enable CCD for fast/small bodies when tunneling warrants its cost.
Events, sensors, and joints
- Sensors report intersection enter/exit without contact response. Use sensor intersection events rather than expecting ordinary collision events.
- Collision groups require compatible membership/filter masks on both colliders. Use
interactionGroupsinstead of hand-building masks unless the format is needed. - Collision payloads may lack a rigidBodyObject for standalone colliders. Inspect the other collider/body safely; do not assume every hit is a named mesh.
- Follow the installed Rapier callback restrictions. In contact-filter hooks, cache body state before the step rather than querying it during Rust's borrowed simulation state.
- Joints connect body refs using local anchors and axes, not world coordinates. Check the hook's exact tuple shape for fixed, revolute, spherical, spring, or rope constraints.
- Read controlled motion and joints for a step-aligned kinematic platform and correctly aligned hinge.
- A collision-aware character controller is separate from moving a mesh or setting a dynamic body's position. Use the installed Rapier character-controller API and test stairs/slopes/grounding.
- Restoring a world snapshot requires matching body creation/handle relationships; it is not a generic way to swap arbitrary scenes beneath existing React refs.
Verify
Check resting contact, collider alignment, impulses, sleeping/waking, and different render frame rates. Test sensor enter/exit, fast-body tunneling, and Strict Mode remounts for the paths used.
Sources
Related skills
More from enzed/r3f-skills and the wider catalog.

r3f-postprocessing
Configure React Three Fiber postprocessing: bloom, selection effects, ambient occlusion, and depth of field.

r3f-shaders
Implement custom GLSL or TSL materials in React Three Fiber with uniforms and vertex deformation.

r3f-textures
Configure textures in React Three Fiber: color spaces, UV channels, sampling, video, and render targets.

r3f-animation
Animate React Three Fiber objects with useFrame, damping, and GLTF clips.

bb-browser
Browser automation with login state for accessing public and private information across 36+ platforms.

fusion-code-conventions
Enforce TypeScript, React, C#, and Markdown code conventions, ADR compliance, and intent documentation.