Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
5335637
chore: migrate to yarn 4 via corepack
DennisSmolek Oct 10, 2026
290df4f
chore!: move to r3f v10, three 0.186, react 19.2 and vitest 5
DennisSmolek Oct 10, 2026
8d99499
build: replace preconstruct with rollup + esbuild + rollup-plugin-dts
DennisSmolek Oct 10, 2026
4bc1587
chore(demo): compile and build on r3f v10 / drei 11
DennisSmolek Oct 10, 2026
6f5aa73
chore: add eslint 9 flat config and prettier 3
DennisSmolek Oct 10, 2026
c57c7c5
ci: refresh workflows and enter changesets alpha prerelease mode
DennisSmolek Oct 10, 2026
a4a0c34
docs: add DEVELOPMENT.md for the yarn 4 / rollup tooling
DennisSmolek Oct 10, 2026
2c12a59
feat!: step physics in the r3f v10 scheduler's fixed-step phase
DennisSmolek Oct 10, 2026
e473000
fix: reuse one debug geometry instead of allocating one per frame (#666)
DennisSmolek Oct 10, 2026
9fe49f5
test: cover scheduler stepping, interpolation, parent space and debug
DennisSmolek Oct 10, 2026
a82ff17
chore: add changeset for scheduler stepping
DennisSmolek Oct 10, 2026
6ef8f89
test: restore the pre-v10 physics snapshot values
DennisSmolek Oct 10, 2026
0d91d9f
refactor: reset the stepper accumulator on timeStep change without us…
DennisSmolek Oct 10, 2026
a6f8a3f
fix: address stepping review (parent order, late ancestor moves, inte…
DennisSmolek Oct 10, 2026
00c990c
test: regressions for nested bodies, late ancestor moves, teleports, …
DennisSmolek Oct 10, 2026
dce14bb
chore: update stepping changeset for review fixes
DennisSmolek Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"mode": "pre",
"tag": "alpha"
}
27 changes: 27 additions & 0 deletions .changeset/r3f-v10-foundation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"@react-three/rapier": major
"@react-three/rapier-addons": major
---

Move to the React Three Fiber v10 stack and modernize the package format.

### Requirements

- `@react-three/fiber` `>=10.0.0-0` (developed against `10.0.0-canary.a056612`; scheduler fixed-step support needs `@pmndrs/scheduler` 0.3+)
- `react` `>=19.0 <19.3` (the range r3f v10 supports)
- `three` `>=0.185.0`
- Node.js 22+ for tooling (`engines`)
- `@react-three/rapier-addons` now peers on `@react-three/rapier` `^3.0.0-0`

### Package format

- Built with rollup + esbuild instead of preconstruct. Each package ships an `exports` map with
ESM (`dist/index.mjs`) and CommonJS (`dist/index.cjs`) builds and matching type declarations
(`.d.mts` / `.d.cts`), and is marked `sideEffects: false`.
- Deep imports into package internals (e.g. `@react-three/rapier/src/...` or `dist/...` files)
are no longer possible; import from the package root.

### Behaviour notes

- Under r3f v10 `useFrame`'s state no longer has `clock`; use `state.elapsed` / `state.delta`
in your own frame callbacks.
17 changes: 17 additions & 0 deletions .changeset/scheduler-fixed-step.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@react-three/rapier": major
---

Step physics on the react-three-fiber v10 scheduler.

- With `updateLoop="follow"` (default) and a numeric `timeStep`, each world steps in its own fixed-timestep scheduler phase (`rapier:fixed:<n>`), which runs after r3f's `physics` phase. Changing `timeStep` or `maxSubSteps` retimes that phase in place, and phases are reused when worlds remount. Rendered transforms are synced once per frame in a new `rapier` phase, before `update`, and interpolated by the phase's overstep. A `rapier:late` pass right before `render` re-applies them if an ancestor moved during `update`. The shared `physics` phase timestep is never changed, and multiple `<Physics>` worlds with different `timeStep`s work side by side. Without scheduler fixed-phase support (`@pmndrs/scheduler` < 0.3), the same behaviour runs on an internal accumulator.
- New `maxSubSteps` prop (default `5`) caps the fixed steps a single frame may run. Surplus time is dropped instead of queued, so slow frames can no longer spiral (#697).
- **Breaking:** `updatePriority` now only orders this world's jobs within their scheduler phase (higher runs first, the r3f v10 convention). It no longer takes over r3f's render loop. Physics always steps before `update`, and r3f keeps rendering.
- `paused` banks no time, so resuming does not burst. `step()` from `useRapier()` works while paused and syncs meshes immediately.
- `useBeforePhysicsStep` and `useAfterPhysicsStep` callbacks receive `(world, dt)`, where `dt` is the step length. Existing single-argument callbacks keep working.
- Collision, contact-force and soft-body tear events are drained after every substep instead of once per frame.
- Bodies are synced parent-first into their parent's current space every frame, so moving, rotating or re-parenting an ancestor of a `<RigidBody>` after mount keeps its visual on the simulated body (#36), and nested bodies no longer lag the body that carries them.
- Interpolation no longer lerps across teleports made in `useBeforePhysicsStep`, manual `step()` calls, `setWorld()`, or `paused`/`interpolate` changes.
- `<Debug>` reuses one geometry and disposes it on unmount, instead of allocating one per frame and leaking on toggle (#666).
- With `frameloop="demand"`, the canvas is invalidated once per frame while any non-fixed body is awake.
- The world is freed after the unmount commit, so child cleanups run against a live world and StrictMode remounts are safe.
26 changes: 26 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Setup
description: Enable Corepack (Yarn 4), set up Node.js with the Yarn cache and install dependencies

inputs:
node-version:
description: Node.js version
default: 22.x

runs:
using: composite
steps:
# Corepack must be enabled before setup-node so its Yarn cache step finds Yarn 4
# (the `packageManager` field), not the runner's global Yarn 1.
- name: Enable Corepack
shell: bash
run: corepack enable

- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: ${{ inputs.node-version }}
cache: yarn

- name: Install dependencies
shell: bash
run: yarn install --immutable
35 changes: 34 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,39 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/packages/react-three-rapier"
directory: "/" # yarn workspaces are discovered from the root
schedule:
interval: "weekly"
groups:
minor-and-patch:
applies-to: version-updates
update-types:
- "minor"
- "patch"
ignore:
# three, react/react-dom and @react-three/* track r3f v10 / drei v11 prereleases;
# major bumps are deliberate, hand-verified upgrades.
- dependency-name: "three"
update-types: ["version-update:semver-major"]
- dependency-name: "@types/three"
update-types: ["version-update:semver-major"]
- dependency-name: "react"
update-types: ["version-update:semver-major"]
- dependency-name: "react-dom"
update-types: ["version-update:semver-major"]
- dependency-name: "@types/react"
update-types: ["version-update:semver-major"]
- dependency-name: "@types/react-dom"
update-types: ["version-update:semver-major"]
- dependency-name: "@react-three/*"
update-types: ["version-update:semver-major"]

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
update-types:
- "minor"
- "patch"
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: CI

on:
pull_request:
branches: [main, next]
push:
branches: [main, next]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
typecheck:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup
- name: Typecheck packages and tests
run: yarn typecheck
- name: Typecheck demo
run: yarn workspace demo typecheck

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup
# vitest resolves the workspace packages from src, so no build is needed first
- name: Test
run: yarn vitest run

build:
name: Build & check packages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: publint + arethetypeswrong
run: yarn check:packages

demo:
name: Build demo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup
- name: Build demo
run: yarn demo:build

lint:
name: Lint & format
runs-on: ubuntu-latest
# Non-blocking until the codebase is reformatted / lint-fixed at the end of the 3.0
# integration (see DEVELOPMENT.md). Remove `continue-on-error` then.
continue-on-error: true
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup
- name: Lint
run: yarn lint
- name: Format
if: ${{ !cancelled() }}
run: yarn format:check
19 changes: 5 additions & 14 deletions .github/workflows/r3-rapier-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v7

- name: Setup Node.js environment
uses: actions/setup-node@v3.6.0
with:
node-version: 22.x

- name: Enable corepack
run: corepack enable

- name: Install Node Dependencies
run: yarn --immutable
- uses: ./.github/actions/setup

- name: Run typedoc
run: yarn docs:build

- name: Setup Pages
uses: actions/configure-pages@v2
uses: actions/configure-pages@v6

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v5
with:
# Upload docs folder
path: "./packages/react-three-rapier/docs"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
28 changes: 19 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
name: Release

# `main` publishes stable releases. `next` is the 3.0 integration branch and is in changesets
# pre mode (.changeset/pre.json, `yarn prerelease:enter`), so the same flow there opens a
# "Version Packages (alpha)" PR into `next` (the action appends the pre tag) and publishes `x.y.z-alpha.n` under the `alpha`
# dist-tag, leaving `latest` untouched. Run `yarn prerelease:exit` before merging `next` into
# `main`.
on:
push:
branches:
- main
- next

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
release:
name: Release
if: github.repository_owner == 'pmndrs'
runs-on: ubuntu-latest
permissions:
contents: write # changesets pushes the version branch
pull-requests: write # ...and opens the "Version Packages" PR
id-token: write # npm provenance / trusted publishing (OIDC)
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v7

- name: Setup Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 22

- name: Install Dependencies
run: yarn --immutable
- uses: ./.github/actions/setup

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: yarn release
version: yarn changeset:version
publish: yarn changeset:publish
commit: "chore(changeset): release packages"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# This is a Yarn 4 workspace, so changesets publishes with `yarn npm publish`, which
# reads YARN_NPM_AUTH_TOKEN rather than NPM_TOKEN. NPM_TOKEN is kept because
# changesets/action uses it to write the .npmrc it checks registry state with.
YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
31 changes: 0 additions & 31 deletions .github/workflows/test.yml

This file was deleted.

7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,9 @@ dist

packages/react-three-rapier/docs

.yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.0.0
v22.22.2
13 changes: 10 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
dist
docs
readme.md
**/dist
**/node_modules
**/coverage
**/docs/out
packages/react-three-rapier/docs
.yarn
yarn.lock
.changeset/**/*.md
CHANGELOG.md
readme.md
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"trailingComma": "none",
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"arrowParens": "always",
"endOfLine": "lf"
}
7 changes: 7 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
approvedGitRepositories:
- "**"

enableScripts: true

nodeLinker: node-modules

npmMinimalAgeGate: 0
Loading
Loading