Reactylon: The React Framework for XR

Perhaps you’ve already exposed this sort of interface/api, but is there a way to create many instances of the same mesh (they share the same geometry, and optionally share the same materials)

Yes, there is a dedicated section about cloning/instancing: Copies, Clones and Instances | Reactylon, the sugar syntax is the instanceFrom prop.

Going off the example you provided, lets say your group of boxes constitutes a single mesh tree. I want to create many instances that all respond to the same hide/show logic at an individual level. That is each group of boxes can be toggled on/off, and each group of boxes can hide/show individual boxes.

Great example to showcase. As the goal is to share the same materials across the boxes, we will use instances instead of clones and, for simplicity, instead of showing or hiding a single box, we will scale its dimensions.

There are two BoxGroup components (representing your single mesh tree), each accepting the following props:

  • name: the name of the box group
  • count: the number of the boxes
  • color: the color of the boxes
  • positionY: the Y position of the box group

When you click on a box, its size toggles between 1 and 2. This change is handled acting on the ref the box so it won’t trigger a re-render.

At the top level, the visibility of the two BoxGroup is managed through HTML buttons, controlled by an external context (primary renderer) and React state. When a BoxGroup is shown, it creates new instances, while it is hidden, it disposes all of them.
Note: the visibility of a BoxGroup doesn’t influence the state of the other one (for instance, try to click on some boxes of one BoxGroup and then toggle the visibility of the other one).

The example is pretty simple, but it demonstrates several key-concepts:

  1. How to sync external updates with the Reactylon rendering context (from primary to secondary renderer)
  2. How to change a property without trigger a re-render (by using ref)
  3. How a React component-based approach simplifies managing a unified entity by encapsulating count, color, and events, making updates and interactions more efficient and scalable.
2 Likes

NICE.

I tweaked your example to render 20k boxes (10k each color), and I don’t notice any lag whatsoever.

This is so awesome! When I get some free time, I’m going to attempt a much more involved large scale demo, and stress test this framework. If feels like you’ve indirectly provided a sort of entity-component system, which is something I’ve always wished babylon.js had a better api for.

1 Like

Hi there! I wanted to share the new features with you:

  • Audio (v1 but as soon as the migration is complete, I’ll move to v2)

    • Ambient sound
    • Spatial sound
    • Spatial sound attached to mesh
  • Physics

    • Havok by default
    • Rigid bodies, motion forces and collision events
    • usePhysics and useHavok hooks

I’ve added the new code sandboxes to the previous message.

And… I’m trying to create more complex examples in the documentation, i hope you like them!

2 Likes

That’s so great! I love it!

1 Like

Big news!

Reactylon 2.0.0 has been released! The framework is now compatible with React 19 and (as Babylon teaches :face_with_hand_over_mouth:) also fully retro-compatible with React 18.

All code sandboxes have been upgraded to version 2.0.0! :rocket:

4 Likes

Hey everyone! Here to say that all code sandboxes and documentation examples have been upgraded to Babylon ^8.0.0!

The transition went smoothly. Huge congrats for the milestone! :clap:t3:

3 Likes

Hi there! I’m excited to share that starting with version 3.0.0, Reactylon is now fully tree-shakable.

To achieve this, I re-engineered the internal logic behind how Babylon.js entities are created.

Previously, the entities were pulled from a static all-in-one import (e.g. import * as BabylonCore from @babylonjs/core). Now, they are dynamically imported from an inventory that is generated during the build process. This is made possible by a custom Babel plugin designed specifically for Reactylon:

What the plugin does:

  • Analyzes JSX at build time to determine which Reactylon components are in use

  • Resolves and imports only the necessary Babylon.js classes from @babylonjs/core and @babylonjs/gui

  • Handles implicit side effects:

    prototype-level, detects method calls in user code and includes necessary modules (e.g. if scene.createDefaultCameraOrLight is used, it automatically includes @babylonjs/core/Helpers/sceneHelpers.js)

    JSX props, parses JSX for specific props and imports corresponding modules (e.g. if <sphere checkCollisions /> is used, it automatically includes @babylonjs/core/Collisions/collisionCoordinator.js)

  • Handles explicit side effects:

    – Allows users to define extra side effects during the plugin initialization

  • Automatically registers used Babylon.js classes in Reactylon’s internal registry.

To determine the right import, the plugin selects the deepest available class implementation by recursively scanning the directory tree. This approach should ensure that the most specific and optimized module is used, preventing unwanted side effects that could compromise tree shaking.

This plugin is fully compatible with Babel (standalone or within frameworks like Next.js and React Native) and works seamlessly with bundlers like Webpack and Vite as long as Babel is part of the toolchain.

If you want to see in action, all code sandboxes have been updated to version 3.0.0 and are now fully tree-shakable! :deciduous_tree: :deciduous_tree:

6 Likes

Nice work man!

1 Like

Wow, what an update :slight_smile:

I am catching up after being away for quite some time, but will do my best to find time this week to play around with the new version. Amazing work!!!

1 Like

hi @SimoneDev - Really great work on reactylon! I was wondering if you wanted to join forces somehow. I guess my general feeling is the community would benefit more from a single library in the long run. Generally speaking it is refreshing to see another way to do essentially the same thing, but as sometimes happens in open source is fragmentation of library choices and more tough choices to devs when getting started. I’m happy to archive my repository, if that’s what makes most sense. On NPM I’m getting about 10,000 downloads/month compared to your ~250 (not that it really matters). It is really nice to see the initiative to bring a new lilbrary to the scene!!! You are doing a few things in a way that I like more than what I’ve done - For example, I’ve often thought of bringing in full tree-shaking with a copy of that same r3f plugin. Maybe it makes sense to try to join the Poimandres collective - there was a bit of discussion in my repo with drcmda about sharing more libs/code between r3f and react-babylonjs.

2 Likes

Hey @brianzinn, first of all, thank you for the kind words. It really means a lot coming from someone whose work has such an impact on the ecosystem.

I totally agree about the fragmentation issue. One upside is that parallel explorations can sometimes lead to fresh perspectives and innovation, but in long run, convergence is definitely healthier for the community.

That said, I’m fully committed to continuing to build Reactylon. It’s been a full-time focus for me over the past year and I see a lot of momentum and potential ahead. I’m genuinely open to the idea of joining forces, though to be honest, I’m not quite sure how we could do that in a way that avoids simply continuing in parallel with two separate repositories. As you know, pillar like the renderer tend to have a domino effect influencing many other architectural decisions.

Of course, I’d never expect you to archive your repository. It has a long history and has clearly made a real impact. Still, I’d really be happy to talk more about what meaningful collaboration could look like, especially if it helps bring things into closer alignment over time.

1 Like

Thanks Simone - I really like what you said. In fact, your parallel exploration has led to innovations and improvements. I’ve been watching and admiring the improvements to r3f over the years - the gltfjsx is another one that would be cool to implement. I was thinking even before you created Reactylon to look at joining a developer collective like Poimandres or create an org or something. I don’t know what joining forces would look like either, but I am grateful you shared your perspective. I absolutely was not intending you to give up any of your contributions! :smiley:

Maybe after some reflection we may come up with an idea on what a good direction is, but two people working together could be cool, too. Maybe we could do a feature comparison and try to get to feature parity where it may matter and then just archive mine. I also really like the extend feature of r3f - I think my renderer was the first with dynamic registration - I’ve always wanted to add support for other libraries like materials as well. Lately I have more ideas than spare time. Cheers.

1 Like

I really like the idea of doing a feature comparison and we could also outline some key requirements moving forward (XR, for instance, really deserves a frictionless starting point more declarative).

Let’s just say i’m genuinely excited about the idea of working together. Whether it’s aligning on shared goals or building something new side by side, there is definitely a lot of potential here. :rocket:

1 Like

You guys joining forces and bringing the best of both worlds should be the wet dream of any react+babylon developer.

Just wanted to say that :slight_smile:

2 Likes

Thanks for the energy boost, comments like this really fuel the motivation!

3 Likes

Hi guys! I’m working on real-world use cases to showcase the power of Reactylon and I wanted share with you the first one: a Vespa configurator that allows to customize the 3D model and, at the end of the journey, visualize it in augmented reality.

The amazing thing is that the full experience is built with just 1500 lines of code!

Here the link if you want to try it!

5 Likes

This is super impressive! So smooth and easy to use.

1 Like

I’m really proud to share that, starting from version 3.1.1, the Grid layout has been added!

It’s amazing because with just a few lines of code, using only grid, row and column, you can create everything from simple to deeply nested complex layouts!

A basic example:

<grid name='grid'>
   <row height={1} >
      <column width={0.5}>
         <rectangle thickness={0} background='#FFD54F'>
            <textBlock name='column-1-text' text={`Row 1\nColumn 1`} />
         </rectangle>
      </column>
      <column width={0.5}>
         <rectangle thickness={0} background='#E53935'>
            <textBlock name='column-1-text' text={`Row 1\nColumn 2`} />
          </rectangle>
      </column>
   </row>
</grid>

But you can also create deeply nested layouts and update them dynamically. For example, in the following demo, each time I click on a cell, it is removed and the layout recalculates automatically.

The hierarchy names (e.g. grid-row-0-col-1-row-1-col-0), are autogenerated by the framework to facilitate debugging).


Everything is documented here:

1 Like