Members Only is the publishing pipeline for BabylonJS Market. You wrote a component in your project, it matured, you want others to use it — this is the tool that gets it there. Underneath it is bjs inject, the reverse of arcade eject.
The eject/inject duality
arcade eject is the consumer-side move. You install @babylonjsmarket/arcade, you scaffold a game, you want to edit one of the built-in components.
Eject copies the component from packages/arcade/src/Components/<Name>/ into your project's src/components/<Name>/, rewrites the sibling imports to point at the package subpath for components you didn't take, and patches src/registry.ts so your local copy overrides the package copy.
bjs inject is the producer-side move. You wrote a component in your project, it survived a couple of games, you want others to install it.
Inject copies it from src/components/<Name>/ into the marketplace library, rewrites the imports the other way, and patches the registry or barrel.
The two tools are intentionally symmetric. Eject moves code outward, inject moves code inward. Imports rewrite in both directions. Tests come along both ways. The folder shape stays stable.
The two targets
bjs inject routes into exactly two namespaces.
arcade— the per-component layout. Each component lives atsrc/components/<Name>/with its.ts,.core.ts,.test.ts, optional.viz.tsx,.panel.tsx, andmeta.json. The project'ssrc/registry.tsgains a lazy resolver line for every injected component.viz— the flat per-layer layout (under@babylonjsmarket/viz's tree). Files are routed intocore/,solid/, orecs/depending on what they do. The matching layer'sindex.tsgainsexport * from './<File>';for each non-test file.
There is no third destination. There is no "publish to npm" path from bjs inject. Members Only stops once your submission is recorded; the next steps (curator review, version bump, npm publish) happen via the operator pipeline.
When to use it
Use Members Only when:
- Your component has been used in more than one game without breaking.
- The public surface — events emitted, events listened to, fields on the Component — has settled.
- You want a downstream consumer to pull your component the same way they pull everything else:
arcade eject <Name>, edit when needed.
When not to
Don't promote something you're still iterating on. The inject is cheap; the renegotiation isn't.
Once your component is in the arcade library and someone has ejected it, your event names and field shapes are a public contract. Rename a field and you break their game.
Don't promote a component with hard-coded references to your game's specifics. The closure walk will pull in siblings (anything imported via ../Sibling/), but it won't generalize a hard-coded asset path or a magic string from your scene JSON. Generalize first; inject second.
Don't promote a component whose tests don't run in isolation. If your test reaches into other parts of your project, the test will go with the inject but the dependencies won't, and the test will fail in the library's CI. Decouple the test before you ship.
What you need before you start
Two things, neither of them surprising:
@babylonjsmarket/cliinstalled globally, which exposes thebjscommand (and with it thebjs injectsubcommand). Node 20+.- A logged-in session via
bjs login— submissions are user-attributed, so authentication is mandatory.
You do not need a local checkout of the arcade or viz library tree. bjs inject runs against a tmpdir and ships the resulting diff to the marketplace API for curator review.
The install and first run section covers both in detail.
What's next
The next section, install and first run, walks through getting the bjs inject command on your $PATH and running a dry-run against a sample component.