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

@needle-tools/editor-sync

v3.0.0

Published

Package providing hooks to connect and apply changes from external editors to the Needle Engine runtime scene

Downloads

270

Readme

@needle-tools/editor-sync

Package providing hooks to connect and apply changes from external editors (like Unity or Blender) to the Needle Engine runtime three.js scene in real-time.

Installation

npm install @needle-tools/editor-sync

Usage

Import the package in your Needle Engine project to enable editor sync at runtime:

import "@needle-tools/editor-sync";

This registers the necessary hooks automatically. The package listens for editor connections and applies incoming property changes to the three.js scene.

To send property changes back to the editor from your components, use notifyPropertyChanged:

import { notifyPropertyChanged } from "@needle-tools/editor-sync";

// Notify the editor that a property was changed at runtime
notifyPropertyChanged(myObject, "position", myObject.position);

How It Works

Editor sync enables real-time property modifications between an external editor and a running Needle Engine web app. Communication happens over Vite HMR (Hot Module Replacement) WebSocket channels.

Architecture Overview

┌──────────────┐    WebSocket (Vite HMR)    ┌──────────────────┐
│  Editor Tool  │ ◄────────────────────────► │  Needle Engine   │
│  (Unity, etc) │    needle:editor:* msgs    │  (Web Runtime)   │
└──────────────┘                             └──────────────────┘
       │                                              │
       │  Exports glTF with                           │  Loads glTF and
       │  NEEDLE_editor extension                     │  registers objects
       │  containing object GUIDs                     │  by GUID in Registry
       ▼                                              ▼
  ┌──────────┐                                ┌──────────────┐
  │ .glb/.gltf│ ──────────────────────────── │ Three.js Scene│
  └──────────┘                                └──────────────┘

Integrating a New Editor Tool

To add editor sync support for a new editor (e.g. Godot, custom tool), you need to implement the following:

1. Connect via Vite HMR

The web runtime communicates through Vite's HMR WebSocket. Your editor needs to connect to the Vite dev server's WebSocket and exchange messages using the HMR protocol.

2. Embed GUIDs in glTF Exports

When exporting scenes to glTF/GLB, add the NEEDLE_editor extension to nodes and materials:

{
  "nodes": [{
    "name": "MyCube",
    "extensions": {
      "NEEDLE_editor": { "id": "unique-guid-for-this-object" }
    }
  }],
  "materials": [{
    "name": "MyMaterial",
    "extensions": {
      "NEEDLE_editor": { "id": "unique-guid-for-this-material" }
    }
  }]
}

The web runtime uses these GUIDs to map editor objects to three.js objects in the scene.

3. Send Property Modifications

Send property changes as HMR messages on the needle:editor:modified-property channel:

{
  "type": "needle:editor:modified-property",
  "data": {
    "guid": "object-guid",
    "propertyName": "position",
    "value": { "x": 0, "y": 1, "z": 0 }
  }
}

4. Property Name Mapping

Properties use glTF conventions for materials and standard names for transforms:

| Editor Property | Sync Property Name | Value Format | |---|---|---| | Position | position | { x, y, z } | | Rotation | rotation | { x, y, z, w } (quaternion) | | Scale | scale | { x, y, z } | | Base Color | baseColorFactor | { r, g, b, a } (linear) | | Base Color Texture | baseColorTexture | data URI (see below) | | Metallic | metallicFactor | number | | Roughness | roughnessFactor | number | | Normal Map | normalTexture | data URI | | Normal Scale | normalTextureScale | { x, y } | | Emission Color | emissiveFactor | { r, g, b } (linear) | | Emission Map | emissiveTexture | data URI | | Occlusion Map | occlusionTexture | data URI | | Occlusion Strength | occlusionStrength | number |

5. Texture Encoding

Textures are sent as base64 data URIs with metadata:

{
  "type": "texture",
  "data": "data:image/png;base64,iVBOR...",
  "filter": 1,
  "anisotropy": 1,
  "wrap": 0,
  "name": "my-texture"
}

| Filter | Value | Wrap | Value | |---|---|---|---| | Point | 0 | Repeat | 0 | | Bilinear | 1 | Clamp | 1 | | Trilinear | 2 | Mirror | 2 |

Supported formats: PNG, JPEG, EXR, HDR.

6. Scene Camera Sync

Sync the editor's scene camera using the special guid "scene-camera":

{ "guid": "scene-camera", "propertyName": "enabled",  "value": true }
{ "guid": "scene-camera", "propertyName": "position", "value": { "x": 0, "y": 1, "z": 5 } }
{ "guid": "scene-camera", "propertyName": "rotation", "value": { "x": 0, "y": 0, "z": 0, "w": 1 } }
{ "guid": "scene-camera", "propertyName": "fov",      "value": 60 }
{ "guid": "scene-camera", "propertyName": "near",     "value": 0.1 }
{ "guid": "scene-camera", "propertyName": "far",      "value": 1000 }

7. Listen for Changes from the Web Runtime

The web runtime can send property changes back to the editor on the needle:editor channel:

{
  "type": "needle:editor:propertyChanged",
  "data": {
    "id": "object-guid",
    "property": "position",
    "value": { "x": 1, "y": 2, "z": 3 }
  }
}

8. Custom Component Handling

Components can implement IEditorModificationListener for custom modification logic:

import type { EditorModification, IEditorModificationListener } from "@needle-tools/editor-sync";

class MyComponent implements IEditorModificationListener {
    onEditorModification(mod: EditorModification): boolean {
        // Return false to use default behavior
        // Return true to handle it yourself
        return false;
    }
    onAfterEditorModification(mod: EditorModification): void {
        // Called after modification is applied
    }
}

Debug Parameters

| URL Parameter | Description | |---|---| | ?debugeditor | Enable debug logging | | ?noeditor | Disable editor sync | | ?editorid=<id> | Set editor instance ID |

Links

Contact

Needle | @NeedleTools | @marcel_wiessler | @hybridherbst