Once your component is in the @babylonjsmarket/arcade library, a downstream consumer can pull it into their project the same way they pull anything else out of the arcade library — with arcade eject. The shape of that round-trip is the contract you sign by publishing.
What a downstream consumer does
They scaffold a project from create-arcade, install @babylonjsmarket/arcade, see your component listed in the registry, and decide they want to edit it locally:
After the eject:
The folder shape is the one you injected — eject preserves it because eject and inject share the same per-component layout.
What gets rewritten
arcade eject reads the file you wrote and rewrites sibling imports based on which siblings were ejected alongside.
- A sibling that was ejected too — say the consumer ran
arcade eject Bouncer Surface— keeps its relative path:../Surface/Surface. Both live under the consumer'ssrc/components/and the path still resolves. - A sibling that was not ejected — say the consumer kept
Surfacein the package — gets rewritten from../Surface/Surfaceto@babylonjsmarket/arcade/Surface. The import now points at the package subpath.
The rewrite is the inverse of what bjs inject does. When you inject, package subpaths collapse to relative paths because the siblings now share a parent. When the consumer ejects, relative paths to non-ejected siblings expand back to package subpaths because the siblings are once again on different sides of the project/package boundary.
The pure-data files — your meta.json, your tests, your Bouncer.core.ts — are copied byte-identical unless they contained one of these sibling imports.
The contract you're signing
By publishing into the arcade library you commit to a few things, all of them eject-shaped:
- Stable filenames. Your
<Name>.ts,<Name>.core.ts,<Name>.test.tsare what shows up in the consumer's project. Renaming any of them is a breaking change for anyone who's ejected. - Stable export names.
BouncerComponent,BouncerSystem,BouncerEventsare referenced by name from scene JSON and from the lazy registry. Renaming any of them is a breaking change. - Stable event names. The strings inside
BouncerEventsare what other Systems subscribe to. Renaming a'bouncer.bounced'to'bouncer.collision'is a breaking change. - Self-contained logic. Anything your component imports via
../Sibling/either lives in the same library (the import rewrites cleanly) or lives in an ecs-side dependency (ecs/babylon/three imports are left alone). Reaching into the consumer's project from inside a published component breaks the round-trip. - No magic strings tied to your game. Hard-coded asset paths, scene names, or layer IDs from your project will follow the component into the library and out into the consumer's project. Either generalize them away or document them as required configuration.
What stays in the library
Your component keeps living in the arcade library after the consumer ejects it. The eject is a copy, not a move. The consumer's local copy overrides the package copy via their project's src/registry.ts — that's the only thing that changes about which copy wins at runtime.
A consumer who ejects and then deletes their local folder reverts to using your published copy. The package install always works.
The viz round-trip
The viz side of the eject story is the same in spirit but different in layout. viz is flat — every file lives in one of three layers — so the eject moves files out of @babylonjsmarket/viz's <layer>/ tree into the consumer's src/components/<Name>/<File>.ts. The layer information is preserved in the file name (your MyDebugger.viz.tsx was already named that way).
The import rewrites use the same symmetry: @babylonjsmarket/viz/<Sibling> collapses to a relative path when the sibling is also being ejected; otherwise it stays a package subpath.
A practical test
The simplest way to know whether your component is eject-compatible is to publish a dry-run-equivalent of the round-trip before you ship: inject into a scratch checkout of the arcade library, then run arcade eject <YourThing> from a fresh create-arcade project that installs your scratch arcade by file: path. If the ejected folder runs your tests green, the round-trip works. If it doesn't — usually because something reached across the boundary — fix it before you publish for real.
What's next
The next section, troubleshooting, lists the real errors bjs inject emits and what to do about each one.