Provides access to a component instance of a specified component type.

Example: This is how you extend this class to create your own custom component:

 1import { Component, Type } from '@wonderlandengine/api';
 3export class MyComponent extends Component {
 4    static TypeName = 'my-component';
 5    static Properties = {
 6        myBoolean: { type: Type.Boolean, default: false },
 7    };
 8    start() {}
 9    onActivate() {}
10    onDeactivate() {}
11    update(dt) {}

.InheritProperties: boolean 

When set to true, the child class inherits from the parent properties, as shown in the following example:

 1import {Component, Property} from '@wonderlandengine/api';
 3class Parent extends Component {
 4    static TypeName = 'parent';
 5    static Properties = {parentName: Property.string('parent')}
 8class Child extends Parent {
 9    static TypeName = 'child';
10    static Properties = {name: Property.string('child')}
11    static InheritProperties = true;
13    start() {
14        // Works because `InheritProperties` is `true`.
15        console.log(`${} inherits from ${this.parentName}`);
16    }

Note: Properties defined in descendant classes will override properties with the same name defined in ancestor classes.

Defaults to true.

.Properties: Record<string, ComponentProperty

Properties of this component class.

Properties are public attributes that can be configured via the Wonderland Editor.


1import { Component, Type } from '@wonderlandengine/api';
2class MyComponent extends Component {
3    static TypeName = 'my-component';
4    static Properties = {
5        myBoolean: { type: Type.Boolean, default: false },
6        myFloat: { type: Type.Float, default: false },
7        myTexture: { type: Type.Texture, default: null },
8    };

Properties are automatically added to each component instance, and are accessible like any JS attribute:

 1// Creates a new component and set each properties value:
 2const myComponent = object.addComponent(MyComponent, {
 3    myBoolean: true,
 4    myFloat: 42.0,
 5    myTexture: null
 8// You can also override the properties on the instance:
 9myComponent.myBoolean = false;
10myComponent.myFloat = -42.0;


Reference types (i.e., mesh, object, etc…) can also be listed as required:

 1import {Component, Property} from '@wonderlandengine/api';
 3class MyComponent extends Component {
 4    static Properties = {
 5        myObject: Property.object({required: true}),
 6        myAnimation: Property.animation({required: true}),
 7        myTexture: Property.texture({required: true}),
 8        myMesh: Property.mesh({required: true}),
 9    }

Please note that references are validated once before the call to start only, via the validateProperties method.

.TypeName: string 

Unique identifier for this component class.

This is used to register, add, and retrieve components of a given type.

.onRegister: (engine: WonderlandEngine) ⇒ void 

Called when this component class is registered.

Example: This callback can be used to register dependencies of a component, e.g., component classes that need to be registered in order to add them at runtime with addComponent, independent of whether they are used in the editor.

1class Spawner extends Component {
2    static TypeName = 'spawner';
4    static onRegister(engine) {
5        engine.registerComponent(SpawnedComponent);
6    }
8    // You can now use addComponent with SpawnedComponent

Example: This callback can be used to register different implementations of a component depending on client features or API versions.

 1// Properties need to be the same for all implementations!
 2const SharedProperties = {};
 4class Anchor extends Component {
 5    static TypeName = 'spawner';
 6    static Properties = SharedProperties;
 8    static onRegister(engine) {
 9        if(navigator.xr === undefined) {
10            /* WebXR unsupported, keep this dummy component */
11            return;
12        }
13        /* WebXR supported! Override already registered dummy implementation
14         * with one depending on hit-test API support */
15        engine.registerComponent(window.HitTestSource === undefined ?
16            AnchorWithoutHitTest : AnchorWithHitTest);
17    }
19    // This one implements no functions

.active: boolean 

Whether this component is active


Set whether this component is active.

Activating/deactivating a component comes at a small cost of reordering components in the respective component manager. This function therefore is not a trivial assignment.

Does nothing if the component is already activated/deactivated.

.engine: WonderlandEngine 

Hosting engine instance.

.isDestroyed: boolean 


true if the component is destroyed, false otherwise.

If erasePrototypeOnDestroy is true, reading a custom property will not work:

1engine.erasePrototypeOnDestroy = true;
3const comp = obj.addComponent('mesh');
4comp.customParam = 'Hello World!';
6console.log(comp.isDestroyed); // Prints `false`
8console.log(comp.isDestroyed); // Prints `true`
9console.log(comp.customParam); // Throws an error

.object: Object3D 

The object this component is attached to.

.type: string 

The name of this component’s type

.copy(src: Record<string, any>) ⇒ Component 

Copy all the properties from src into this instance.

Note: Only properties are copied. If a component needs to copy extra data, it needs to override this method.


1class MyComponent extends Component {
2    nonPropertyData = 'Hello World';
4    copy(src) {
5        super.copy(src);
6        this.nonPropertyData = src.nonPropertyData;
7        return this;
8    }

Note: This method is called by clone. Do not attempt to: - Create new component - Read references to other objects

When cloning via clone, this method will be called before start.

Note: JavaScript component properties aren’t retargeted. Thus, references inside the source object will not be retargeted to the destination object, at the exception of the skin data on MeshComponent and AnimationComponent.

Returns: Reference to self (for method chaining).

srcRecord<string, any>The source component to copy from.

.destroy() ⇒ void 


Remove this component from its objects and destroy it.

It is best practice to set the component to null after, to ensure it does not get used later.

1   c.destroy();
2   c = null;

.equals(otherComponent: undefined | null | Component) ⇒ boolean 

Checks equality by comparing whether the wrapped native component ids and component manager types are equal.

Returns: Whether this component equals the given component.

otherComponentundefined | null | ComponentComponent to check equality with.

.init() ⇒ void 

Triggered when the component is initialized by the runtime. This method will only be triggered once after instantiation.

.onActivate() ⇒ void 

Triggered when the component goes from an inactive state to an active state.

Note: You can manually activate or deactivate a component using: active.

.onDeactivate() ⇒ void 

Triggered when the component goes from an activated state to an inactive state.

Note: You can manually activate or deactivate a component using: active.

.onDestroy() ⇒ void 


Triggered when the component is removed from its object.

Note: You can remove a component using: destroy.

.reset() ⇒ Component 

Deprecated: Use resetProperties instead.

.resetProperties() ⇒ Component 

Reset the component properties to default.

Note: This is automatically called during the component instantiation.

Returns: Reference to self (for method chaining).

.start() ⇒ void 

Triggered when the component is started by the runtime, or activated.

You can use that to re-initialize the state of the component.

.update(delta: number) ⇒ void 

Triggered every frame by the runtime.

You should perform your business logic in this method. Example:

 1import { Component, Type } from '@wonderlandengine/api';
 3class TranslateForwardComponent extends Component {
 4    static TypeName = 'translate-forward-component';
 5    static Properties = {
 6        speed: { type: Type.Float, default: 1.0 }
 7    };
 8    constructor() {
 9        this._forward = new Float32Array([0, 0, 0]);
10    }
11    update(dt) {
12        this.object.getForward(this._forward);
13        this._forward[0] *= this.speed;
14        this._forward[1] *= this.speed;
15        this._forward[2] *= this.speed;
16        this.object.translate(this._forward);
17    }
deltanumberElapsed time between this frame and the previous one, in seconds.

.validateProperties() ⇒ void 

Validate the properties on this instance.

Throws: If any of the required properties isn’t initialized on this instance.