Needle Engine is a web-first 3D framework built on three.js for building games, configurators, AR/VR experiences, and interactive websites.
Built-in: Rapier Physics | WebXR (incl. iOS) | Multiplayer & VOIP | Blender & Unity Integration
Built on three.js and the glTF standard, Needle Engine delivers flexible, extensible web experiences with built-in collaboration and XR support. Use it standalone with npm or with powerful editor integrations for Unity and Blender.
Changelog | Documentation | Samples | Showcase | API Reference
npm install @needle-tools/engine
Try it now on StackBlitz | Getting Started Guide
import { Behaviour, serializable } from "@needle-tools/engine";
export class MyComponent extends Behaviour {
@serializable()
speed: number = 1;
start() {
console.log("Component started on:", this.gameObject.name);
}
update() {
this.gameObject.rotateY(this.context.time.deltaTime * this.speed);
}
}
import { Behaviour, Rigidbody, BoxCollider } from "@needle-tools/engine";
export class PhysicsBox extends Behaviour {
awake() {
// Add a physics body — Rapier is built in, no extra install needed
const rb = this.gameObject.addComponent(Rigidbody);
rb.useGravity = true;
// Add a collider
this.gameObject.addComponent(BoxCollider);
}
}
import { Behaviour, syncField } from "@needle-tools/engine";
export class SyncedCounter extends Behaviour {
// Automatically synced across all connected clients
@syncField()
count: number = 0;
onPointerClick() {
// Reassign to trigger sync (this is required for sync to work)
this.count = this.count + 1;
}
}
import { onStart, onUpdate } from "@needle-tools/engine";
onStart((context) => {
console.log("Engine started!");
});
onUpdate((context) => {
// Called every frame
});
WebXR & AR — immersive experiences on Android and iOS
WebXRImageTracking — AR image targets with full tracking lifecycleWebXRPlaneTracking — AR surface detectionScene & Asset Management
SceneSwitcher — load different scenes / hierarchies by URLAssetReference — runtime asset loading by URLPhysics & Interaction — Built-in Rapier physics engine
Rigidbody, BoxCollider, SphereCollider, MeshCollider — full physics simulationDragControls — click-and-drag 3D objects with zero codeSpatialTrigger — proximity and enter-zone detectionMultiplayer & Networking — real-time collaboration out of the box
SyncedRoom + @syncField() — automatic state synchronizationVoip — built-in WebRTC voice chatPlayerSync — player object sync on join/leaveSyncedCamera — camera sync for observer sessionsRendering & Effects
Animation & Media
VideoPlayer — full video playback componentAudioSource — 3D spatial audioFramework Integration — works with React, Vue, Svelte, or vanilla JS/TS
Needle Engine works standalone with just npm — no editor required. For asset-heavy workflows, use our editor integrations:
| Preview | Example | Description | Links |
|---|---|---|---|
![]() |
Multiuser Cross device experience, Desktop, AR & VR (Sandbox) | Real-time collaborative multiplayer sandbox experience with WebXR on Android and iOS | |
![]() |
Image Tracking AR | AR image tracking example (iOS and Android). See docs | |
| Scrollytelling Bike Example | Timeline Animation using ScrollFollow, ViewBox and FocusRect | Project on Github | |
| See-Through Walls | See-Through component sample | ||
| Cursor Follow | Cursor Follow sample | ||
| Animate Anything | Interactive animation system | Code on Stackblitz • three.js Example | |
| Postprocessing Effects | Custom magnifier effect with post-processing | Code on Stackblitz | |
![]() |
Unity ShaderGraph to MaterialX & mtlx materials | Using @needle-tools/materialx | |
| Camera Focus DIV 1 | Responsive layout with camera focus | Code on Stackblitz | |
| Camera Focus DIV 2 | Click-to-move camera focus example | Code on Stackblitz | |
| FastHDR Loading | 10x faster than EXR, non-blocking, 95% less GPU memory | Code on Stackblitz • Learn more | |
| Scrollytelling Example | Scroll, physics and cursor interaction: a playful 3D interactive scrollytelling website | Included in Samples Package | |
| AR Restaurant | Interactive AR restaurant experience | Code on Github | |
| Custom Loading Overlay | Wait for LODs with custom loading states | Code on Stackblitz | |
| React Shopping Cart | E-commerce integration with React | Code on Stackblitz | |
👋 More examples on samples.needle.tools, docs.needle.tools and in the Needle Engine Stackblitz Collection
🌵 Needle •
Github •
Twitter •
Discord •
Forum •
Youtube
ctx.sceneData or needle.sceneData. Types are generated automatically by a Vite plugin whenever your scene files change — no configuration needed. Works with both local and remote (Needle Cloud) assets. The API shape (particularly $components and $object accessors) may evolve based on feedback. Can be disabled with dts: { enabled: false } in your Vite plugin config.// fully typed, with autocomplete for every node and component
const cam = ctx.sceneData.MyScene.MainCamera.$object; // THREE.PerspectiveCamera
const orbit = ctx.sceneData.MyScene.MainCamera.$components.OrbitControls; // typed!
ReferenceError crashes. The engine now provides SSR-safe base classes and skips browser-dependent initialization on the server. Core rendering still happens client-side — SSR support means your app can import and reference engine code server-side without errors.<needle-engine> and other web components — first-class support for React, Preact, SolidJS, and other JSX-based frameworks with full autocomplete and type checkingcontext.lights array and context.mainLight getter for easy access to all scene lights and the primary directional lightneedlePlugins() can now be called without arguments — the Vite command is resolved automatically. This simplifies setup in frameworks like SvelteKit where defineConfig doesn't expose the command:export default defineConfig({ plugins: [sveltekit(), needlePlugins()] });
postprocessing library even in projects that don't use postprocessing, increasing bundle size unnecessarilyAnimatorControllerBuilder for building animator controllers from code (experimental)onBeforeXRSessionRequest eventgetComponent by string name (experimental)GroundProjectionsetParamWithoutReload losing URL hashnode_modules/.needle/logs). This is useful for local AI to help debugvolume property and speaking eventonSyncInstantiate and onSyncDestroy callbacksrequestOwnership now returns a PromiseaddComponent generates deterministic component GUIDs for reliable networking of runtime-added componentssyncInstantiate automatically adds to prefabProvider and assigns GUIDcontext.postprocessing and exported from @needle-tools/engineText component absolute font URL handling@needle-tools/materialx to 1.6.0:
gltf_pbr materials per the glTF specification