npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

babylon-lite-hook

v0.0.2

Published

React hooks and Suspense-ready scene component for Babylon Lite (@babylonjs/lite)

Readme

babylon-lite-hook

React hooks and a Suspense-ready <SceneComponent> for Babylon Lite (@babylonjs/lite) — the WebGPU-first, tree-shakable renderer from the Babylon.js team.

This is the babylonjs-hook you already know, ported to Babylon Lite. The JSX is intentionally the same — in most cases you change the library you import scene-building functions from and everything else keeps working. Because Babylon Lite's setup is genuinely async (createEngine, registerScene, startEngine and asset loading all return Promises), the component integrates with React Suspense: pass a fallback and it renders while the engine, your scene setup and the first frame complete.

NPM version NPM downloads

Requirements

  • React 19+ (uses the use API for Suspense)
  • @babylonjs/lite 1.8+
  • A WebGPU-capable browser — Babylon Lite is WebGPU-exclusive by design (no WebGL fallback)

How to Install

npm i babylon-lite-hook @babylonjs/lite

Basic Usage

import React from 'react';
import {
  addToScene,
  attachFreeControl,
  createBox,
  createFreeCamera,
  createGround,
  createHemisphericLight,
} from '@babylonjs/lite';
import SceneComponent from 'babylon-lite-hook';
import './App.css';

let box;

const onSceneReady = (scene) => {
  // This creates and positions a free camera (plain data — no methods)
  const camera = createFreeCamera({ x: 0, y: 5, z: -10 }, { x: 0, y: 0, z: 0 });
  scene.camera = camera;

  // This attaches the camera to the canvas
  attachFreeControl(camera, scene.surface.canvas, scene);

  const engine = scene.surface.engine;

  // This creates a light, aiming 0,1,0 - to the sky
  addToScene(scene, createHemisphericLight([0, 1, 0], 0.7));

  // Our built-in 'box' shape.
  box = createBox(engine, 2);

  // Move the box upward 1/2 its height
  box.position.y = 1;
  addToScene(scene, box);

  // Our built-in 'ground' shape.
  addToScene(scene, createGround(engine, { width: 6, height: 6 }));
};

/**
 * Will run on every frame render.  We are spinning the box on y-axis.
 */
const onRender = (scene, deltaMs) => {
  if (box !== undefined) {
    const rpm = 10;
    box.rotation.y += (rpm / 60) * Math.PI * 2 * (deltaMs / 1000);
  }
};

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <SceneComponent
          antialias
          onSceneReady={onSceneReady}
          onRender={onRender}
          id="my-canvas"
          fallback={<div>loading…</div>}
        />
      </header>
    </div>
  );
}

export default App;

Suspense

Everything between "canvas mounted" and "first frame rendered" is one Suspense window: engine creation, your onSceneReady (which may be async — load glTF models, environments, …), scene registration and the first rendered frame. While that's pending, the fallback renders; the canvas itself stays mounted the whole time (Babylon Lite needs it), so style the fallback as an overlay if you want a loading screen on top of the canvas.

const onSceneReady = async (scene) => {
  const engine = scene.surface.engine;
  scene.camera = createDefaultCamera(scene);
  // the component suspends until this resolves — no loading-state bookkeeping needed
  addToScene(scene, await loadGltf(engine, 'model.glb'));
};

<SceneComponent onSceneReady={onSceneReady} fallback={<LoadingOverlay />}>
  <SceneUI />
</SceneComponent>;

Children render only once the scene is ready, so useScene() / useEngine() inside them never return null in practice. Initialization failures (e.g. no WebGPU support) propagate to the nearest error boundary:

<ErrorBoundary fallback={<p>This experience needs a WebGPU-capable browser.</p>}>
  <SceneComponent onSceneReady={onSceneReady} fallback={<LoadingOverlay />} />
</ErrorBoundary>

Hooks

| hook | description | | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | useScene() | The Babylon Lite SceneContext (or null outside a ready <SceneComponent>). | | useEngine() | The EngineContext. Also reachable as scene.surface.engine. | | useCanvas() | The rendering HTMLCanvasElement. | | useBeforeRender(cb) | Registers cb(scene, deltaMs) before each frame; auto-unregisters on unmount. | | useCamera(createCameraFn, autoAttach?) | Creates a camera, assigns scene.camera and (by default) attaches pointer controls for ArcRotate/Free cameras — detached and cleared on unmount. |

const SpinningLabel = () => {
  const scene = useScene();
  useCamera((scene) => createArcRotateCamera(-Math.PI / 2, Math.PI / 2.5, 8, { x: 0, y: 0, z: 0 }));
  useBeforeRender((scene, deltaMs) => {
    // per-frame logic
  });
  return null;
};

Porting from babylonjs-hook

The JSX shape is unchanged — swap the import and port onSceneReady to Babylon Lite's function-based API (see the porting guide).

| babylonjs-hook | babylon-lite-hook | | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | onSceneReady(scene) | Same prop, now optional and may be async — the component suspends until it resolves. | | onRender(scene) | Same prop, with the frame delta as a bonus second argument: onRender(scene, deltaMs). | | antialias | Same prop — maps to msaaSamples: 4 / 1 (Lite defaults to 4x MSAA). | | adaptToDeviceRatio | Same prop — Lite adapts by default; false maps to maxDevicePixelRatio: 1. | | engineOptions / sceneOptions | Same props — Lite's EngineOptions / SceneContextOptions. | | renderChildrenWhenReady | Superseded by Suspense: children always render when the scene is ready. Prop is accepted but ignored. | | observeCanvasResize | Not needed: Lite resizes the engine from the canvas layout every frame. Prop is accepted but ignored. | | useBeforeRender(cb, mask?, insertFirst?, callOnce?) | useBeforeRender(cb) — Lite has no observable masks; cb receives (scene, deltaMs). | | useAfterRender(cb) | Not available — Babylon Lite has no after-render hook. Open an issue if you need it. | | useCamera(fn, autoAttach?, noPreventDefault?) | useCamera(fn, autoAttach?) — attach/detach is handled through Lite's attachControl/attachFreeControl. | | SceneContext (React context) | Renamed to SceneReactContext to avoid clashing with @babylonjs/lite's SceneContext type. The useScene() hook is unchanged. | | withEngineCanvasContext HOC | Removed — use the useEngine() / useCanvas() hooks. |

Related

Made with ♥ by Brian Zinn