> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/scenes-sdk7/architecture/composites.md).

# Composites

A *composite* is a file that describes a tree of [entities and components](/creator/scenes-sdk7/architecture/entities-components.md). Instead of writing code to create each entity one by one, you can store that structure in a composite file and spawn the whole thing with a single call.

You might already work with composites without realizing it:

* Every scene has a `main.composite` file. It holds everything you added and configured visually in the [Scene Editor](/creator/scene-editor/get-started/about-editor.md). This file is loaded automatically when your scene starts.
* [Custom Items](/creator/scene-editor/interactivity/custom-items.md) are saved as `composite.json` files. Each Custom Item is a composite that you can reuse across scenes.

This page covers how to spawn a composite from code at runtime, for example to spawn a Custom Item dynamically as part of your scene's logic.

## Spawn a composite

Spawning a composite takes two steps: **load** the composite file, then **spawn** it. Loading is asynchronous and spawning is synchronous, so the pattern is always load-then-spawn:

```ts
import { engine, Composite, getCompositeProvider } from "@dcl/sdk/ecs";

export async function spawnBarrel() {
  const src = "barrel.composite";
  const provider = getCompositeProvider();
  if (!provider || !provider.loadComposite) return;

  // 1. Load the composite from its file
  const resource = await provider.loadComposite(src);

  // 2. Spawn it: creates all its entities and components
  const barrel = Composite.instance(engine, resource, provider);
  return barrel;
}
```

`provider.loadComposite(src)` reads the composite file and loads it into memory. In a normal scene built with `@dcl/sdk`, a composite provider is already set up for you, you reach it with the `getCompositeProvider()` function from `@dcl/sdk/ecs`.

`Composite.instance()` then creates all the entities described in the composite, with all their components, and returns the **root entity** of the spawned tree. Use this returned entity to read or change components later, for example to reposition or remove the spawned item.

{% hint style="info" %}
**💡 Tip**: To do the same thing without writing code, use the **Spawn Entity** action in the Scene Editor. See [About spawning entities](/creator/scene-editor/interactivity/smart-items-advanced.md#about-spawning-entities).
{% endhint %}

{% hint style="warning" %}
**📔 Note**: You must load a composite before you spawn it. `Composite.instance()` is synchronous and can only spawn a composite that's already in memory. Only `main.composite` is bundled with your scene and available from the start; any other composite file must be loaded with `loadComposite()` first. To check synchronously whether a composite is already available, use `provider.getCompositeOrNull(src)`.

`loadComposite()` is idempotent: it keys each composite by its `src` string, so calling it again with the same path doesn't reload the file, it returns the already-loaded composite. You can safely call it before every spawn without worrying about loading the same file twice.
{% endhint %}

## Position a spawned composite

To place the spawned composite at a specific position, rotation, or scale, set a `Transform` component on the root entity returned by `Composite.instance()`.

```ts
import { engine, Composite, getCompositeProvider, Transform } from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";

export async function spawnBarrel() {
  const src = "barrel.composite";
  const provider = getCompositeProvider();
  if (!provider || !provider.loadComposite) return;

  const resource = await provider.loadComposite(src);

  // Spawn the composite at a specific position
  const barrel = Composite.instance(engine, resource, provider);
  Transform.createOrReplace(barrel, {
    position: Vector3.create(8, 0, 8),
  });
}
```

{% hint style="warning" %}
**📔 Note**: `Transform.createOrReplace()` replaces the root entity's existing Transform component. Only the root entity is affected, child entities keep their positions relative to the root.
{% endhint %}

## Current limitation: nested composites

Spawning works for self-contained composites and Custom Items. A composite can reference another composite from one of its entities, but `loadComposite()` does **not** recurse into those nested references: it only loads the file you pass it.

When spawning, `Composite.instance()` recurses into nested references that are already in memory. If a nested composite isn't loaded (anything other than `main.composite`, the only composite bundled with your scene), that branch logs a warning and is skipped. To spawn a composite with nested references, call `loadComposite()` for each referenced file first — or simpler, keep the composites you spawn self-contained.

## Related pages

* [Entities & Components](/creator/scenes-sdk7/architecture/entities-components.md) — the building blocks a composite describes.
* [Custom Items](/creator/scene-editor/interactivity/custom-items.md) — reusable items stored as composites.
* [Smart Items - Advanced](/creator/scene-editor/interactivity/smart-items-advanced.md#about-spawning-entities) — spawn composites with no code, using the Spawn Entity action.
* [Scene Files](/creator/scenes-sdk7/kinds-of-projects/scene-files.md) — where `main.composite` lives in your scene project.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/scenes-sdk7/architecture/composites.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
