v3.3.5
17 October 2026
- fix(reconcile): measure without upgrading page custom elements
#523 - fix(clip): re-anchor a fixed outer <svg> like a fixed HTML box
#522 - perf: release the idle decode iframe, cheaper reconcile walk
6822e82 - fix(styles): read cross-origin sheets through a fetched copy
3592434 - fix(styles): keep frozen heights from losing 1/64px in Chromium
36e7e29 - docs: note that download() uses DPR 1 and scale sets its resolution
793500b
Full Changelog: https://github.com/zumerlab/snapdom/compare/v3.3.4...v3.3.5
9.7.3
-
[@mantine/schedule]Add slotLabelInterval prop to DayView and WeekView to display time labels more often than once per hour -
[@mantine/schedule]Add option to customize business hours minutes and change colors -
[@mantine/schedule]MobileMonthView: AddwithWeekendDaysprop -
[@mantine/charts]Fix right Y axis children rendering (#9295) -
[@mantine/hooks]use-scroller: Fix next click being ignored after a drag ends by leaving the container (#9294) -
[@mantine/hooks]use-event-listener: Fix listener being removed after re-render when options object is passed inline (#9292) -
[@mantine/core]ScrollArea: Add --scrollarea-offset-size CSS variable (#9290) -
[@mantine/core]Cascader: Fix ArrowLeft and ArrowRight not being mirrored in RTL (#9286) -
[@mantine/hooks]use-throttled-callback: Handle reentrant calls (#9284) -
[@mantine/core]Radio, Chip: Fix readOnly prop not preventing value changes (#9282) -
[@mantine/core]Select: Fix onChange option argument type not including null (#9281) -
[@mantine/core]Switch: FixreadOnlyprop not preventing toggle (#9280) -
[@mantine/core]Fix searchable inputs ignoring typing when rendered in another window or iframe (#9278) -
[@mantine/hooks]use-focus-trap: Fix focus not being fully trapped when used with macOS Full Keyboard Access off
v4.64.8
2026-10-17
- Ensure chunk hashes change when sourcemap comments change (#6509)
- Resolve some relative import resolution edge cases (#6522)
- #6509: fix: include sourcemap comments in chunk hashes (@snoopuppy582, @wangxpych, @lukastaegert)
- #6522: fix(browser): match node's join and relative for "." and ".." segments (@luantaraschi, @lukastaegert)
- #6577: Update dtolnay/rust-toolchain digest to 686976e (@renovate[bot])
- #6578: Update minor/patch updates (@renovate[bot])
- #6579: Update swc monorepo (major) (@renovate[bot], @lukastaegert)
- #6580: Lock file maintenance (@renovate[bot], @lukastaegert)
- #6581: Update dependency eslint-plugin-unicorn to v78 (@renovate[bot])
🎉 Release v1.1.0
- Sheets: Add workbook-level iterative calculation with configurable iteration limits and convergence thresholds.
- Sheets: Support configurable line spacing for cell text.
- Charts (Pro): Add 3D column, bar, line, area, and pie charts.
- Charts (Pro): Support logarithmic value axes for 2D charts.
- Docs: Add zoom and fullscreen controls to the toolbar.
- Docs (Pro): Add table border presets to the ribbon.
- PDFs (Pro): Add ribbon controls for editing, annotations, zoom, and fullscreen.
- Collaboration (Pro): Allow hosts to disable automatic URL-based document loading.
- Improve cell editing and worksheet-switch focus, and preserve table column order when saving.
- Fix XLOOKUP error handling, SORT calculations, and named-range updates after worksheet renames.
- Correct relative-date filtering and calendar boundaries.
- Improve drawing positioning and selection, and prevent flicker when switching worksheets.
- Pro: Improve document table resizing, selection performance, and shape-editing undo/redo.
- Pro: Improve imported PDF text dragging, rendering, and editing.
- Pro: Improve collaboration reconnection and offline edit recovery, and isolate offline caches by user.
- Refine Slides menus and shape controls, mobile editing, and accessibility labels.
- Iterative calculation: Replace
FFormula.setMaxIteration()and global cycle-reference settings withFWorkbook.setCalculationSettings(). Iterative calculation is disabled by default. - Node.js presets:
@univerjs/preset-docs-node-coreand@univerjs/preset-sheets-node-coreare no longer included in new releases. Use plugin-based initialization for Node.js integrations. - Formula imports: Import
FormulaReorderControllerfrom@univerjs/sheets-formulainstead of@univerjs/sheets-formula-ui. - Custom chart renderers (Pro):
EChartRenderModelno longer accepts constructor options, andIEChartRenderModelOptionsis removed. Lifecycle handling now usesemitChartEvent()instead of cache-clearing hooks. - Collaboration (Pro): Sync pending offline edits before upgrading. Set the current user before loading documents. Hosts that manage document loading themselves can set
enableUrlUnitLoader: false.
Full changelog: v1.0.4…v1.1.0
slate@0.143.0
-
#6321
9ed1e7dThanks @dylans! - Addeditor.getSplitProperties(node, path)to choose the properties copied to the new right-hand node byTransforms.splitNodes. The default remainsNode.extractProps(node). Applications can omit or replace IDs while preserving text marks for Enter, fragment insertion and partial-range transforms.BaseEditornow requiresgetSplitProperties;createEditorsupplies it. Structural editor implementations and mocks must add the method.
v10.0.0-alpha.6: Going WebGPU First
After feedback from the Paris conference, it was decided to make v10 a clean break for some major portions of r3f to better align with the web and ThreeJS ecosystem. Alpha 6 is also the biggest alpha so far, with more than 200 commits since alpha 5.
In alpha 5, The new Renderer was opt-in through a property tag: <Canvas renderer>, so nothing broke. The feedback was that a major version is the time to make the break, given how important WebGPU is to the future of the web and that threejs itself is mostly focused on WebGPU & TSL. Node materials, compute-shaders, and the rendering pipeline only function in the new Renderer.
We wanted v10's default to match where three, and the rest of the web, is heading.
The new Renderer (WebGPURenderer) is Standard with WebGPU, however it can be set or fall back to WebGL2. Many features written with TSL will still function and work. This is NOT WebGPU vs WebGL entirely, its simply the old WebGL ONLY renderer and the newer one with newer features.
If you have custom GLSL, or rely on older libraries and tools built on GLSL shaders, change one import:
- import { Canvas } from '@react-three/fiber'
+ import { Canvas } from '@react-three/fiber/legacy'
That's the only change. Hooks and libraries keep importing from @react-three/fiber, because every entry shares the same core.
If you get it wrong, R3F tells you. A GLSL material on a WebGPU canvas logs a warning pointing at /legacy. A node material on a /legacy canvas throws a clear error instead of crashing on the first frame. gl={...} on the default import also throws, pointing you to /legacy.
@react-three/fiber/webgpu is redundant now that WebGPU is the default. It still works, but it's deprecated and will be removed in the first beta.
R3F's core no longer imports three.js at all. Each renderer lives in its own small module, and the default import loads WebGPU only when the first <Canvas> mounts.
Two renderers in one package could easily mean both of them in your bundle. Now a /legacy app carries only WebGLRenderer, and a default-import app carries only WebGPURenderer (Which again, can fallback to WebGL).
A library that imports hooks from @react-three/fiber adds no renderer and no second copy of R3F to your app, whichever entry you chose. We check this on every build: CI bundles sample apps with Vite and esbuild and confirms which renderer each one contains.
useThree, useFrame and onCreated from @react-three/fiber are typed for WebGPURenderer, so state.renderer.compute(...) works without a cast. From /legacy they're typed for WebGLRenderer. Before, the hooks were typed for either renderer, and WebGPU-only members needed a cast or extra setup.
Libraries that support both renderers can import from the new @react-three/fiber/extension entry.
useUniforms, useUniform, useNodes, useLocalNodes, useBuffers, useGPUStorage and useRenderPipeline moved out of @react-three/fiber/webgpu and into @react-three/tsl. Change the import, and apart from useRenderPipeline (below) they work as before.
These hooks are WebGPU-only and have been changing faster than the rest of R3F. A separate package lets them ship on their own schedule and keeps them out of WebGL apps. It is also the first package built on @react-three/fiber/extension, the same public surface any library can use. That shows the extension story works.
The package brings several improvements:
Uniforms and nodes you read by name now work directly in TSL. Before, both of these lines needed a cast:
const { uTime, uColor } = useUniforms()
material.colorNode = uColor.mul(sin(uTime))
For more precision, register your uniforms once. Every hook and state.uniforms then knows their names and exact types, and a typo becomes a type error. Nodes, buffers and GPU storage register the same way. It's optional: everything above works without it.
// uniforms.ts
export const globalUniforms = { uTime: 0, uColor: new Color('hotpink') }
declare module '@react-three/tsl' {
interface Register {
uniforms: typeof globalUniforms
}
}
// anywhere in your app
const { uTime } = useUniforms()
uTime.value // number
Give it a dependency array, and [] builds the graph once. It also tracks which shared uniforms and nodes it actually read, so it rebuilds only when one of those is replaced. Before, registering any uniform anywhere rebuilt every graph that used the hook.
const { colorNode } = useLocalNodes(({ uniforms }) => ({
colorNode: uniforms.uColor.mul(sin(time)),
}), [])
It also handles nodes that go onto a three object, like fog. Return a function: the graph is built during render, then installed after commit, and the cleanup runs when the component unmounts. This used to take a placeholder return value plus a separate useThree and useEffect.
useLocalNodes(({ scene, uniforms }) => {
const fogNode = fog(uniforms.fogColor, rangeFogFactor(uniforms.near, uniforms.far))
return () => {
scene.fogNode = fogNode
return () => {
scene.fogNode = null
}
}
}, [])
Mount a component with useRenderPipeline and the effect is on. Unmount it and the effect is gone. Before, the pipeline kept rendering until you called reset(), and StrictMode or Fast Refresh built a second scene pass.
function Bloom() {
useRenderPipeline(({ renderPipeline, passes }) => {
renderPipeline.outputNode = bloom(passes.scenePass.getTextureNode())
})
return null
}
// {bloomOn && <Bloom />} toggles the effect
To keep an effect running after its component unmounts, pass { persist: true } as the third argument.
<Canvas id="main" primary>…</Canvas>
<Canvas>…</Canvas> {/* shares "main" automatically */}
<Canvas share={false}>…</Canvas> {/* gets its own renderer */}
Mark the canvas that owns the renderer with primary, and every other WebGPU canvas shares it. In alpha 5 this was set up inside the renderer options with primaryCanvas, which was hard to find and easy to get wrong. scheduler is now a Canvas prop too, on every entry including /legacy.
Sharing one GPU device across canvases is one of WebGPU's real wins, so it should be the easy path. While building this we also fixed multi-canvas under the WebGL2 fallback, where secondary canvases used to render blank. We also stopped a secondary canvas from overwriting the primary's shadows and tone mapping. Thanks to @rubenmarcus for both reports and fixes.
The physics phase of the frame loop now uses a fixed timestep of 1/60 of a second. This comes from @pmndrs/scheduler 0.3. A physics job runs once for every full step of time that has passed, always with the same delta. On a 144 Hz display it sometimes skips a frame. On a slow frame it catches up with several steps.
with one step per frame, a simulation ran more than twice as fast on a 144 Hz monitor as on a 60 Hz one. A fixed timestep is how physics engines expect to be driven. state.overstep tells you how far the frame is between two steps, so you can draw smooth motion between them:
useFrame((_, dt) => world.step(dt), { phase: 'physics' })
useFrame(({ overstep }) => mesh.position.lerpVectors(previous, current, overstep))
If you want the background, Glenn Fiedler's Fix Your Timestep! is the classic explanation of this technique, including why the interpolation step matters.
Any phase can get its own timestep with setPhaseTimestep(). If you'd rather keep one step per frame, you can switch physics back.
R3F now works smoothly with the parts of React 19 that mount, hide and remount components: StrictMode, Fast Refresh and <Activity>. In practice that means fewer leaks, and fewer surprises when you hot-reload or hide a scene.
With WebGPU, a renderer that gets left behind keeps holding on to the GPU, so cleaning up properly matters more than ever.
- Hide a scene with
<Activity>and the 3D content hides with the page around it. Objects keep their ownvisiblestate when they come back. - Unmounting cleans up right away. A Canvas shuts down as soon as React removes it, not half a second later, and the renderer R3F created goes with it. If you passed in your own renderer, R3F leaves it alone.
- Hot reloads and StrictMode keep your scene. React's extra mounts no longer tear down and rebuild the Canvas.
- Settings you change at runtime stick. A Canvas re-render only re-applies the props that changed, so
setDprorsetFramelooparen't undone. - Sharp on every screen. Drag the window to another display, or zoom, and the canvas picks up the new pixel ratio.
- React 19.3 is supported, and a
<ViewTransition>inside a Canvas no longer stalls.
No more manual needsUpdate. Some material props, like transparent, flatShading, side and vertexColors, are compiled into the shader. Changing one of them used to do nothing until something told three to recompile. That's one of the most common "why isn't my prop working?" questions.
Before (v9):
function Glass({ transparent }) {
const ref = useRef()
// without this effect, toggling `transparent` has no visible effect
useEffect(() => {
ref.current.needsUpdate = true
}, [transparent])
return <meshStandardMaterial ref={ref} transparent={transparent} opacity={0.5} />
}
After (v10):
function Glass({ transparent }) {
return <meshStandardMaterial transparent={transparent} opacity={0.5} />
}
The same goes for adding or removing a texture. Props three already handles itself, like color and opacity, are left alone, so you don't pay for extra recompiles.
A few more things that just work now:
- Image backgrounds.
<Canvas background="/sky.png">used to throw on.png,.webp, plain.jpganddata:URLs. All of them load now. frameloop="demand"redraws when you remove an object. It used to stay on screen until something else triggered a frame.state.glstill works. It's an alias forstate.renderer, so drei'sOrbitControlsand friends keep working on WebGPU. The deprecation notice shows only if something actually readsgl.onUpdateis gone. It hooked into reconciler internals and fired on unrelated updates. An effect,useFrameor a ref callback does the job more reliably.
The ESLint plugin got its biggest update yet, going from 2 rules to 20. Version 1.0.0-alpha.6 ships alongside this release, and it's the fastest way to move an app to v10.
A migration config for v9 apps. Add it next to recommended while you upgrade, run eslint --fix, and take it out once you're done:
// eslint.config.js
import threePlugin from '@react-three/eslint-plugin'
export default [threePlugin.configs.recommended, threePlugin.configs.migration]
It finds the v9 patterns that changed, and --fix rewrites the safe ones for you. It covers state.gl and the old clock, numeric useFrame priorities, removed Canvas props and imports (including the deprecated /webgpu), onUpdate, and <color attach="background">. We ran it over our own examples for this release.
New rules for common performance traps, in recommended:
- objects rebuilt on every render through
args - TSL nodes built inline in material props, which recompile the shader every render
setStatecalled in the frame loop- loaders called in effects instead of
useLoader - Canvas props or materials the entry you imported can't use, such as GLSL on WebGPU
The plugin now ships flat configs and works with ESLint 8, 9 and 10. Install it with npm install -D @react-three/eslint-plugin@alpha.
Tested on a real GPU. Separately, CI now runs a set of tests on an actual WebGPU device, using Dawn in Node, and compares the rendered pixels. Before, everything GPU-related was mocked or checked by hand in a browser.
Most of these throw with a message that names the fix.
- The default import renders with WebGPU. GLSL scenes and WebGL-only libraries import
Canvasfrom/legacy. - TSL hooks import from
@react-three/tsl. <Canvas shadows>becomesrenderer={{ shadows }}(WebGPU) orgl={{ shadows }}(/legacy).renderer={{ primaryCanvas }}becomes<Canvas primary>, andrenderer={{ scheduler }}becomes<Canvas scheduler>.physics-phase jobs run on a fixed timestep. Step your simulation by thedeltayou're given.useRenderPipelinestops rendering when the component that configured it unmounts. Pass{ persist: true }to keep the old behaviour.onUpdateis removed.- Split gain map environments are gone. Use a single-file Ultra HDR
.jpginstead. @react-three/fiber/webgpuis deprecated and will be removed in the first beta.
The v10 breaking changes page lists every change since v9, what to do about it, and which alpha it landed in. The v10 migration guide walks through each one. If you're upgrading a v9 app, start with the eslint-plugin's migration config.
npm install @react-three/fiber@alpha @react-three/tsl@alpha three@latest
This is still an alpha, and the WebGPU default is the biggest change v10 makes, so we especially want to hear from you. Tell us which libraries break on the default import, and which ones you had to move to /legacy. Report problems in issues and share everything else in discussions.
| Package | Version |
|---|---|
@react-three/fiber |
10.0.0-alpha.6 |
@react-three/tsl |
10.0.0-alpha.6 (first alpha) |
@react-three/test-renderer |
10.0.0-alpha.6 |
@react-three/eslint-plugin |
1.0.0-alpha.6 |
All are published under the alpha dist-tag. They need three >=0.185.0 and React >=19.0 <19.4.
Full changelog: CHANGELOG-ALPHA.md → 10.0.0-alpha.6
create-rari-app@0.5.33
See CHANGELOG.md for details.
Full Changelog: https://github.com/rari-build/rari/compare/create-rari-app@0.5.32...create-rari-app@0.5.33
rari@0.17.7
See CHANGELOG.md for details.
Full Changelog: https://github.com/rari-build/rari/compare/rari@0.17.6...rari@0.17.7
@rari/use-cache@0.17.7
See CHANGELOG.md for details.
Full Changelog: https://github.com/rari-build/rari/compare/@rari/use-cache@0.17.6...@rari/use-cache@0.17.7