[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)