[HN Gopher] React Three Ecosystem
___________________________________________________________________
React Three Ecosystem
Author : bpierre
Score : 95 points
Date : 2025-05-10 13:02 UTC (9 hours ago)
(HTM) web link (www.react-three.org)
(TXT) w3m dump (www.react-three.org)
| tlarkworthy wrote:
| note three.js [1] has nothing to do with React out of the box
| though, this page highlights an atypical way of using three.js
| through a popular React binding.
|
| [1] https://threejs.org/
| jasonjmcghee wrote:
| You might be getting downvoted for saying it's an "atypical"
| way of using three.js. the pmnd.rs community (for example) is
| quite large.
|
| I understand why people like the declarative nature of react
| three fiber, but it's quite unfortunate that it requires
| something like code sandbox to allow modification / working
| with it on the web- but that's by nature due to being react.
|
| Vanilla three.js can be written surprisingly similarly, if you
| are disciplined about breaking things up into
| functions/components. And no react necessary / can embed a code
| editor and allow direct modification.
| eyelidlessness wrote:
| For what it's worth, this is also true of whatever else one
| might express with JSX: imperative code (and syntax, and
| semantics) can be structured in a way that closely resembles
| declarative code... _with discipline_.
|
| It's doesn't have to be especially onerous discipline if you
| embrace it, but it becomes considerably more onerous as it
| becomes more social: if some members of a team/contributors
| to a project embrace it more/less than others, that
| difference in commitment becomes a constant source of
| friction.
| mikebelanger wrote:
| > It's doesn't have to be especially onerous discipline if
| you embrace it, but it becomes considerably more onerous as
| it becomes more social: if some members of a
| team/contributors to a project embrace it more/less than
| others, that difference in commitment becomes a constant
| source of friction.
|
| That's one of the stronger arguments for opinionated pre-
| processors/frameworks/libraries like
| Typescript/TSX/JSX/React in general. Because it abstract
| away those things that only some team members would
| embrace, you effectively make _everyone_ embrace them. That
| leads to less friction.
|
| But this reduced friction comes at a cost: more complex
| abstractions and incidental bugs related to that
| complexity. And as far as the procedural vs declarative:
| after a certain degree of complexity, I find myself
| introducing procedural codes within useEffects, useMemos
| anyways
| ttfkam wrote:
| Exactly, as seen with Threlte as a counterpoint.
|
| https://threlte.xyz/
| throwaway314155 wrote:
| That all seemed fairly obvious to me.
| talkingtab wrote:
| When I was new to the integration of threejs and react I found
| these examples to be just amazing.
|
| https://r3f.docs.pmnd.rs/getting-started/examples
| chrisweekly wrote:
| The screenshots look cool, but (on my iPhone) the 1st one I
| tried to view was in a code sandbox that threw an error.
|
| The examples here
|
| https://threejs.org/examples/#webgl_animation_keyframes
|
| seem to work great on my phone...
| MortyWaves wrote:
| R3F is great but almost all the code sandbox demos have been
| broken for years at this point
| esperent wrote:
| Yeah, they went all in on Codesandbox early on, and at the
| time that was a good idea.
|
| But very soon after Codesandbox made the switch to
| containers and started chasing monetization. I saw an
| interaction between the creators of each on Twitter at the
| time where Codesandbox promised not to throttle or limit
| R3Fs examples. But I don't think they fully kept that
| promise.
| throwaway314155 wrote:
| I'm guessing that Safari on iOS doesn't support any of the
| necessary webgl here? Every example shows up with a blank
| component with a question mark emoji at the center.
| hombre_fatal wrote:
| React's threejs/pixijs bindings are a great example of what vdom
| diffing can let you do.
|
| Since they bring their own reconcile(a, b, diff) function to
| React, these libs can turn: const world = new
| World() const player = new Player()
| world.add(player) // somehow wire up the code to keep
| // player.pos updated
|
| Into: const [x, setX] = useState(0)
| return <World> <Player x={x} /> </World>
|
| In other words, you write declarative code, and it does the hard
| imperative work of adding/removing/disposing/updating things for
| you.
|
| Just like how it helps you sync your data model to underlying
| stateful DOM nodes; the idea can be applied on top of any
| stateful system.
| cjonas wrote:
| Just to clarify, you'd write the bottom code (declarative) and
| the library translates it to the above (imperative) code?
| MortyWaves wrote:
| That's right
| cjonas wrote:
| Are there any guides on using the "react style" framework
| (JSX / State) to generate outputs other than DOM? I've been
| interested in the idea of doing something similar for JSON
| or markdown document generation.
| cwackerfuss wrote:
| I don't have a good guide for you, but this is the lib
| you use to create custom React renderers:
|
| https://www.npmjs.com/package/react-reconciler
| didgeoridoo wrote:
| This imperative/declarative shift happened as part of UIKit ->
| SwiftUI too. However, it's still pretty well accepted that if
| you're doing anything "complicated" you're going to end up
| writing UIKit imperative code.
|
| I wonder if there's any research (PL or maybe even more
| philosophical) on whether declarative approaches can logically
| cover all imperative use cases.
|
| Basically: is there something special about "verbs"
| (imperative) that let you do things that "nouns" (declarative)
| cannot, at least within reasonable verbosity constraints?
| nicce wrote:
| Aren't declarative approaches just abstractions over
| imperative? Somehow you need to get there. (Processor
| executes instructions, in the end)
| eyelidlessness wrote:
| A (the?) major area where this is generally considered
| unanswered, and active in PL research, is "effects" (as in,
| side-effects).
| banalico wrote:
| I think there are declarative languages that are Turning-
| complete, like Prolog, etc. So declarative approaches should
| be equally good.
| hombre_fatal wrote:
| Yeah, one of the qualities of the abstraction is how often
| you have to reach for the escape hatch, how nice it is to use
| the escape hatch, and whether it's an escape hatch vs. just
| two clean modes of tooling working together.
|
| SwiftUI has failed pretty much all of those for me.
|
| In react-pixi / react-three, you have your declarative
| component tree alongside a `useTick`/`useFrame` function that
| you can use to do more surgical work, and it works well
| together. Each component can tap into the tick to update
| itself. const Enemy = ({ initalPos, size })
| => { const [pos, setPos] = useState(initialPos)
| useTick(dt => { setPos(/* Move in a circle */)
| }) return <Sprite
| src="/enemy.png" size={size}
| pos={pos} /> }
|
| I've migrated a few medium-sized pixi/three projects to their
| React wrappers, and the code cleaned up so well that I could
| work on them again.
|
| Before that, I'd tried modeling games in Elm and then using
| its port system to send the game state to JS which then
| updates the pixi/three world. But it's exactly this
| updateWorld(oldWorld, newState) that's hard to write, yet
| that's what these libs do for you.
| gf000 wrote:
| Well, you can interpret the program's text as a declarative
| (and completely static) approach to describe what will happen
| at runtime.
|
| But you can actually see this dichotomy in template
| libraries, they usually have constructs making them fully
| Turing-complete (loops, conditionals, etc).
| eyelidlessness wrote:
| Minor nit, because this is one of my weird special interests:
| this (being render-agnostic) isn't necessarily a property of
| React's _virtual DOM_. It's a property of JSX being explicitly
| specified without semantics.
|
| For instance, Solid also supports custom JSX renderer, but
| doesn't use a VDOM to achieve that.
|
| I find it helpful to think of JSX as analogous to a macro (in
| the lispy sense of the term), except that its syntax and
| implementation are decoupled. Most compiler tooling assumes the
| implementation maps to a function call, but even that isn't
| strictly required (and again, Solid is a counter example).
| ttfkam wrote:
| And JSX is not needed either, as seen with Threlte.
|
| https://threlte.xyz/
|
| When all you know is React, everything gets viewed through
| that limited lens.
| hombre_fatal wrote:
| Sheesh.
|
| The point is about the declarative abstraction and how it's
| useful for people who don't know what "React Three" might
| entail, not to enumerate all the frameworks that have it
| under a submission about "React Three Ecosystem".
| hombre_fatal wrote:
| JSX gets compiled to a tree of function calls, but the hard
| part is done using react (or solid, or svelte, or ...) to
| hook in to the lifecycle of nodes in that tree.
| brundolf wrote:
| Something I wish is that you could "render" JSX agnostically
| and just get a JSON data structure describing a tree of tags,
| which is not specific to the platform or even the framework,
| and then you could pass that off to whichever subsystem for
| whichever purpose (or even serialize it or send it over a
| wire). We wouldn't need separate build plugins for each JSX-
| using framework, you'd just pass them your data
| vmg12 wrote:
| You can build your own jsx renderer and get exactly that,
| it's not that difficult.
| brundolf wrote:
| Right, but only with a custom transpilation step. It
| would be nice if there were only a single standard JSX
| transpilation that all the frameworks and platforms
| ingested the output of
| whstl wrote:
| It kinda is! The only difference between JSX transpiler
| outputs is the factory function (and the Fragment
| component). For React the factory function it's
| `React.createElement`, for Preact it's `h`.
|
| Babel has a pragma property, and esbuild allows you to
| pass it in the command line: `--jsx-factory=h`.
|
| https://esbuild.github.io/content-types/#auto-import-for-
| jsx
| brundolf wrote:
| I knew it transpiled to a function call, though I didn't
| know babel lets you parameterize that without writing a
| custom plugin
| darepublic wrote:
| This declarative system often is less intuitive once you get
| into the nitty gritty of things imo. Showing the hello world
| most basic example proves nothing
| jonas21 wrote:
| It's great... except that it turns out to be a performance
| pitfall if the state needs to be frequently updated. The React
| Three Fiber docs mention this here:
|
| https://r3f.docs.pmnd.rs/advanced/pitfalls#avoid-setstate-in...
|
| To fix this, they suggest using useRef and manually updating
| the object. But then your code ends up just as complicated, if
| not more so, than if you had just stuck with vanilla three.js.
| rafram wrote:
| Yeah, I can only imagine what removing an element from the
| middle of a thousand-element array of entities would do. This
| has always been a performance weak point for React, but React
| trees aren't typically rebuilt from the root 60 times a
| second. With this, they are.
| afavour wrote:
| Sadly I've lost the URL but there was once a great comparison
| of Svelte vs React for this exact functionality. The
| performance was orders of magnitude better IIRC.
|
| React code looks great, the dev experience is fantastic. But
| user experience sometimes less so. Hooks kind of hide what's
| going on.
| baxuz wrote:
| The only way to have performant rendering in a React app is
| to eject from React's rendering pipeline -- that is, to not
| use it at all.
|
| State should basically only be used as "keyframes"
| ericmcer wrote:
| Yeh that seems problematic because you no longer have access to
| the render loop, you are letting React manage your render loop
| which seems kinda problematic for a game where you want very
| granular control over what happens each iteration, fps, etc.
| nawgz wrote:
| Has ThreeJS updated to start using X3D (https://www.x3dom.org/)
| yet?
|
| Taking a quick look at [the
| docs](https://r3f.docs.pmnd.rs/getting-started/introduction)
| linked above, I see the use of Canvas. Fair enough.
|
| I start using X3D at work in order to enable some cool
| functionality showing steps to build an assembly in 3D, and it's
| actually insane how high the performance is. It's all HTML
| components, so I wrote a super thin React wrapper (essentially
| the scene needs to be manually loaded once, that's about all) and
| have been cruising with that.
|
| Effortless to fly, rotate, hide or highlight parts, decompose
| things into x3d assets, and so on.
|
| It might have issues somewhere, I haven't widely tested browser
| compat or anything, but it's curious to me how little I see it
| versus how much I see ThreeJS when it seems that X3D is the more
| capable platform.
| cyberax wrote:
| Another example of this is React-Native-Skia:
| https://shopify.github.io/react-native-skia/docs/getting-sta...
|
| It uses a virtual DOM to diff the desired state and the current
| one: https://shopify.github.io/react-native-
| skia/docs/canvas/cont...
|
| If you're interested how it's implemented, that's the source
| code: https://github.com/Shopify/react-native-
| skia/blob/main/packa...
___________________________________________________________________
(page generated 2025-05-10 23:00 UTC)