React+babylonjs: WebGL context lost



Calling engine.dispose() within React’s useEffect doesn’t seem to properly destroy the context.

@ZoeLeee the sandbox link is broken.

You’d wanna keep a reference to the engine on the side (maybe in state or a singleton) and call it later. Best way is to rely on react as an event trigger system.

I’ve restored the link address. I wish for the Babylon engine to be properly disposed of upon the React component’s destruction.

seems to work fine on the sandbox, what’s the issue ?

After roughly 27 consecutive clicks, warnings about excessive context may appear. Please refer to the GIF I’ve uploaded for reference.

I’ve temporarily resolved the issue this way.


It looks like your component is rerendered, and it calls the engine.dispose() each time when unmounting. I’d suggest hoisting the engine to a context. This means that if you re-mount the Canvas component, a reference to Engine will still exist.

1 Like

Even if I place the engine within the context, I still need to initialize the engine within the component where the canvas resides. When this component is unmounted, I still need to call engine.dispose(), which I believe might lead to the same issue.

No no, it is not necessary. That is the thing, you don’t need to dispose of the engine every time as it is initialized in the context. I’ll try to find some time to make a prototype for you.

I did have some time to make this working proto for you, but it is a little messy. Sorry for that (-:
Link to codesandbox

It has a context that refers to an engine. Your App, which initializes Engine once and put it into the context.
The canvas component takes the reference to the engine and uses its rendering canvas so you can mount it to your components. And, only canvas remounting happens when the button is clicked, but the engine is not disposed. You can, of course, adjust it, and probably you want to resize the engine after mounting, but it is already a part of your business logic.

You’re amazing! Thank you for taking the time to create this demo. Now, there’s no need to dispose of the engine frequently. Wishing you a joyful life ahead!

@brianzinn I think this also applies to react-babylonjs
And calling loseContext seems to help.

thanks @dennemark for sharing - definitely looks like a good addition. i have an RTX 3060 video card, but I think this happens more on lower-end devices/hardware. I wonder if that is something upstream that should be done - like an opt-out to not call automatically onDispose()?

Yes @brianzinn the issue mainly appears on low-end devices. But i am not sure if this issue only appears when using react. It seems like react is not properly cleaning up the canvas?
But what you are proposing would be close to @denysp solution to keep the engine running even though the component is disposed, right? I was rather thinking of adding the loseContext() function to the unmounting function of . But am still surprised this is even necessary.
( is a component oft the react-babylonjs library)

@dennemark I don’t think we want to keep the engine running… we should pass this as true probably and add an opt-out (reverse):
EngineOptions | Babylon.js Documentation (


Ah nice! I wasn’t aware of this flag! I agree, we could use true as a default! Bit annoying to have this flag set on false for backwards compatibility, but it is great that it is documented.

I’m thinking to add this - otherwise it can be passed in with the other options - does that look reasonable:

if (engineOptions === undefined) {
  engineOptions = {
     loseContextOnDispose: true

I thought about adding a keepContextOnDispose property that defaulted to false, but I think that could be a bit confusing.

looks good to me! i do not think keepContextOnDispose is necessary.

thanks @dennemark - i have the context lost default change sitting here with other new stuff:
add: WebGPUEngine and FallbackEngine by brianzinn · Pull Request #315 · brianzinn/react-babylonjs (

I’ll wait to see if there’s any community feedback. Not expecting any TBH. Will push out a new version on the weekend likely. Cheers.

1 Like