Higher-level visualization and interaction components for robot and ai faces.
npm install @vizij/render> Three.js + React renderer, scene store, and helper controllers for Vizij faces.
This package exposes the Vizij canvas component along with hooks, stores, and GLTF helpers that power Vizij’s real-time character visualisation. It is the foundation that other packages (@vizij/rig, @vizij/orchestrator-react, etc.) build upon.
---
1. Overview
2. Installation
3. Usage
4. Store & Hooks
5. Controllers & Helpers
6. Development & Testing
7. Publishing
8. Related Packages
---
- Vizij renders a fully managed @react-three/fiber canvas with sensible defaults for orthographic cameras and safe-area overlays.
- A Zustand-powered store (useVizijStore) tracks renderables, controllers, and transient state. Hooks let you read or mutate slices without re-rendering entire scenes.
- Utilities (loadGLTF, loadGLTFBlob, export helpers) streamline loading rigged GLTF assets and exporting scene snapshots. The tuple helpers now return [world, animatables, animations], where animations contains parsed clip metadata for any channels embedded in the GLB.
- Controllers wrap common behaviours (e.g., pointer interaction, safe-area visualisation) so you can compose features quickly.
---
``bashpnpm
pnpm add @vizij/render three @react-three/fiber @react-three/drei zustand @vizij/utils
Peer requirements:
-
react >= 18
- three >= 0.170
- @react-three/fiber >= 8
- @react-three/drei >= 9
- zustand >= 5
- Optional UI integrations: tailwindcss >= 4.1 (declared as a peer for theme utilities)Ensure these versions align with the rest of your app to avoid duplicate React or Three.js instances.
---
Usage
`tsx
import { Vizij, useVizijStore } from "@vizij/render";
import { useEffect } from "react";export function VizijCanvas() {
const setDebug = useVizijStore((state) => state.setDebugState);
useEffect(() => {
setDebug((debug) => ({ ...debug, showGrid: true }));
}, [setDebug]);
return (
rootId="default/root"
namespace="default"
showSafeArea
style={{ width: "100%", height: 480 }}
/>
);
}
`Wrap the component tree with
VizijContext.Provider if you want to supply a custom store; otherwise the Vizij component creates one internally.---
Store & Hooks
-
useVizijStore(selector?) – Access or mutate the renderer store with automatic subscription management.
- useVizijStoreGetter, useVizijStoreSetter, useVizijStoreSubscription – Fine-grained accessors when you need optimised reads/writes.
- useFeatures() – Inspect feature flags registered in the store.
- Store types (VizijData, VizijActions) are exported from store-types for strongly typed selectors.The store tracks world graph entries, controllers, debug overlays, and renderable metadata. See
src/store.ts for the full surface.---
Controllers & Helpers
- Controllers under
src/controllers encapsulate input handling, camera logic, and other behaviours. Compose them with your own React components.
- loadGLTF / loadGLTFBlob simplify loading rig assets and extract animatable metadata used by @vizij/rig.
- export helpers produce snapshots of the current scene (useful for tooling or exporting frames).All exports are re-exported through
src/index.tsx, so a simple import { loadGLTF } from "@vizij/render" works.$3
Vizij scenes persist authoring metadata inside GLBs so third-party tools see baked animation, while Vizij runtimes retain orchestrator graphs and clips.
- Every renderable still carries a
RobotData extension in userData describing features and animatable bindings.
- The exporter now writes a root-level extensions.VIZIJ_bundle block following the schema in src/types/vizij-bundle.ts. It contains rig graphs, pose configs, stored Vizij clips, and provenance hashes.
- Use exportScene(group, { bundle, animations }) to embed both the Vizij bundle and optional baked THREE.AnimationClip instances. The helper attaches the bundle only for the export call and restores the original object.
- When loading assets, prefer loadGLTFWithBundle / loadGLTFFromBlobWithBundle to retrieve { world, animatables, bundle, animations }. The legacy tuple helpers return [world, animatables, animations] if you only need the renderer state.
- The new animations field exposes VizijAnimationClipData[], which maps each glTF animation channel back to Vizij animatable ids (RobotData.features.*.value.id). Each track provides component-aware times/values arrays so runtimes can register clips without re-parsing the GLB.
- extractVizijBundle(scene) and applyVizijBundle(scene, bundle) (under src/functions/vizij-bundle.ts) let advanced tooling inspect or mutate bundles without triggering a fresh export.With this structure, authoring tools can round-trip orchestrator assets while shipping native glTF animations for viewers that do not understand Vizij.
---
Development & Testing
`bash
pnpm --filter "@vizij/render" build
pnpm --filter "@vizij/render" test
pnpm --filter "@vizij/render" typecheck
pnpm --filter "@vizij/render" lint
pnpm --filter "@vizij/render" size
`tsup produces both ESM and CJS bundles with type declarations. Tests run via Vitest (currently smoke-level), and size-limit guards against unexpected bundle growth.---
Publishing
.github/workflows/publish-npm.yml.1. Align dependency versions (
three, @react-three/*, zustand, Vizij packages) and generate a changeset:
`bash
pnpm changeset
pnpm version:packages
`
2. Validate locally:
`bash
pnpm install
pnpm --filter "@vizij/render" build
pnpm --filter "@vizij/render" test
pnpm --filter "@vizij/render" typecheck
pnpm --filter "@vizij/render" lint
pnpm --filter "@vizij/render" exec npm pack --dry-run
`
3. Tag the release as npm-render-vX.Y.Z and push the tag. The workflow will publish with provenance metadata.---
Related Packages
@vizij/rig – Hooks that consume the renderer to load rigged models.
- @vizij/animation-react` – React bindings that feed animation values back into the renderer.Questions or contributions? Open an issue so we can keep the renderer API and docs sharp for the whole Vizij ecosystem. 🎨