---
title: "Package (asset type)"
description: "A package is an asset — a <Name>.package/ folder that bundles components, modules, scenes, presets, tools, and any other typed sub-assets under one identity, installed into a world as one unit.…"
section: "Types"
slug: "types-package"
canonical: "https://origozero.ai/docs/types-package"
updated: "2026-08-22T07:41:56.106499814+00:00"
tags: ["asset-type", "reference"]
---

# Package (asset type)

A **library** is the addressable root scope content resolves under
(`@builtin`, `@<name>`) — a whole world mounted into this one under a
namespace, via `zm.installLib` / `world.installLibrary`. A package is
an asset that lives inside such a root, and one library holds as many
packages as its author put there. A package is installed by guid the
way every asset is (`zeromind.install`, `zm.installAsset`).

## When to use one

- You're authoring a coherent feature suite (character controller
  stack, voxel engine, UI kit, animation library) and want to ship
  it as one install target.
- You want a stable identity worlds can install and resolve sub-assets
  against (`@<lib>::pkg.sub_module`).
- You want versioning + a per-package metadata layer that travels with
  the contents.

If you're authoring inside a single world and don't need a separate
install lifecycle, you don't need a package — drop your `.component`
/ `.module` / etc. directly in `/zero/source/`. Packages are for
cross-world distribution.

## Where it lives

- Source: `/zero/source/.../<Name>.package/` (or, for legacy
  packages, a folder containing `package.yaml` at its root).
- Identity: `<Name>` (the `.package` suffix collapses in identity —
  mirrors `.module`). A file at `<Name>.package/<sub>/init.luau`
  resolves under the same identity it would at `<Name>/<sub>/init.luau`.
- Folder shape (container-style — open child set):
  - `package.yaml` — metadata (name, version, description).
    **Required.**
  - `README.md` — instance documentation. **Required.**
  - `.metadata` — agent-editable tags + free-form fields. **Required.**
  - Sub-asset folders: any combination of `.component/`,
    `.module/`, `.scene/`, `.preset/`, `.tool/`, `.toolbox/`,
    `.material/`, `.shader/`, etc.

The validator permits unlisted children (`allow_unlisted: true`) by
design — packages are open containers.

## How to create one

```luau
asset.create("package", "<Name>")
-- Creates: /zero/source/<Name>.package/
--   package.yaml   (metadata scaffold)
--   README.md      (instance README template)

-- `folder` places it in a subfolder of /source instead of the root:
asset.create("package", "<Name>", { folder = "systems" })
```

Then scaffold sub-assets inside it:

```luau
local pkg = asset.resolve("<Name>.package")
asset.create("component", "Spinner", { into = pkg })
asset.create("module", "util", { into = pkg })
```

## How it operates

1. **Registration.** Writing `package.yaml` indexes the package with
   the package registry.
2. **Install.** A package is installed by guid, the way every asset
   is: `zeromind.install` from the shared library, or
   `tools.use("zm", "installAsset", <guid>)` inside the engine. The
   install writes the package's files (and the deps its `.refs`
   record) into this world's source, so its sub-assets resolve here.
   `tools.use("zm", "preview", <guid>)` reports what an install would
   write before it writes anything.
3. **Sub-asset resolution.** Because `.package` collapses in
   identity, sub-asset paths work whether the package folder is
   suffixed (`<Name>.package/<sub>`) or not (`<Name>/<sub>`).
4. **Updates.** `tools.use("zm", "updates")` lists installed content
   with upstream changes available; re-running the install pulls them.
5. **Metadata.** `package.yaml::name` overrides the folder stem if
   present (rare); `version` + `description` are surfaced in the
   package index.
6. **Hot reload.** Edits to sub-assets hot-reload as normal; edits to
   `package.yaml` reload package metadata.

## Discovery

- `asset.list("package")` — every registered package.
- `asset.inspect("<name>")` — sub-asset catalog, source, this type
  README.
- `cat /zero/source/<Name>.package` — same summary.
- `library.list()` — the library assets registered in this world,
  including the ones packages under an installed library contribute.

## Authoring conventions

- Name packages by their feature (`voxels`, `cameraRigs`,
  `dialogSystem`), not by their owner — the host library is the
  `@<lib>::` scope prefix.
- Cluster cohesive sub-assets together. A "character controller"
  package should ship the controller component, its preset configs,
  its supporting modules, and a demo scene — not just the component.
- Document the package's surface in `README.md` — what install
  installs, what each sub-asset does, how they relate. Agents reading
  `cat /zero/source/<Name>.package` get the full picture in one shot.
- Version conservatively — breaking a package means breaking every
  world that installed it. Use semantic version bumps.

## Common pitfalls

- **Missing `package.yaml`.** Without it the folder isn't recognized
  as a package even if it has a `.package/` suffix.
- **Dependency installs.** A package that depends on another package
  must declare it (in `package.yaml::dependencies` once supported)
  and the parent world must install dependencies in order.
- **Identity collapse.** Sub-asset paths skip the `.package` suffix.
  Don't include `.package` in `require` strings.

## Referencing inside a package: the `~` rule

`~` means **this package**, resolved structurally from the referring file's own
location. It is the only package-specific syntax. It is rename-safe (no package
name is ever written) and library-agnostic (it never names the host library, so
it survives `@builtin` being renamed or the package being mounted elsewhere).
`~.tail` maps to `<pkg>.package/tail` from anywhere inside the package.

| Referencing from | Use | Example |
|---|---|---|
| An asset/module **inside this package** | `~.tail` | `require("~.modules.myThing")`, `shader: "~.shaders.myThingBlend"` |
| A **different package** under the same root | root-relative identity | `require("@root::systems.otherPkg.modules.x")` |
| A **different library's** public API (a deliberate external dependency) | `@otherlib::…` | `require("@physics::modules.rigidbody")` |

**Never write `@builtin::` (or any host-library name) to reference your own
package** — that couples the package to the library it currently lives in and
breaks if the library is renamed or the files move. Use `~.`. It works from
Luau `require()` and from asset-reference strings in data files (a material's
`mat.yaml` `shader:` field, a component's default asset ref); the engine
resolves it against the referring file's own package. In a `.luau` file holding
a `~.` ref as a string, resolve it explicitly against your own path:
`asset.resolve("~.materials.myThingStandard", "material", __FILE__)`.

`~.` is the package-relative self-reference; `@root::` is the root-relative one
(the library root, or the world source tree for non-library content). The
`core/requiring-modules` guide covers the root model in full.

A package that ships substantial functionality should include a `.guide` asset
(a `<name>.guide/guide.md` folder anywhere under the package); the `guides` tool
discovers it live, so collaborators find the system the way they find built-in
guides. A package's test suite reaches the shared `Test` framework through its
enclosing asset: `local Test = asset.containing(__FILE__).modules.shared`
(`asset.containing` returns the deepest enclosing typed asset, the `.testSuite`,
not the outer `.package`).

## Related types

- Any of `.component`, `.module`, `.scene`, `.preset`, `.tool`,
  `.toolbox`, `.material`, `.shader`, `.style`, `.service`,
  `.importer` — packages bundle these.
