8 minutes
Inject and Track Your Submission
TL;DR —
bjs injectsends a copy of your component to the marketplace as a diff payloadThe bundle inject sends: the new files plus the registration patches needed to wire the component into the package.. Thenbjs submissions(list, show, withdrawPulling a still-pending submission back out of the queue with bjs submissions withdraw.) tracks it from pending, through a curatorThe person who reviews a submission like a pull request — reads the code, runs the test, and merges or returns it with notes.'s review, to mergedThe terminal success state: the component shipped into the catalog and credits were awarded.. New here: the full submissionOne injected component (or set) sitting in the marketplace review queue, tracked by a numeric id. lifecycle. You dry-run first, follow the pending→reviewing→merged state machineA model where a thing occupies one named state at a time and can only move along defined transitions — here, a submission's lifecycle., read reviewer notesThe written feedback a curator attaches to a submission, visible in bjs submissions show once review starts., and earn creditsThe marketplace's spendable balance, earned when a submission merges and spent to acquire catalog components. when a merge lands. This is where the rest of the course pays off.
Last lesson, you could read Magnet cold and say where bjs inject would send it. It goes to arcade, because nothing in its main files imports viz. That routing check was the last step before the folder on your disk becomes a submission in the queue. Now you run bjs inject Magnet. A second later, your component is off your machine. But open src/components/Magnet/ and it is all still there. Every file is untouched, and your gitThe tool that tracks versions of your files over time, so every change is recorded and nothing is lost. history is intact. So what left? Not your component. A copy of it, shaped like a pull requestThe standard way coders propose changes to a shared codebase: a bundle of edits someone else reads, runs, and either accepts (merges) or sends back with notes. Often shortened to PR.: a list of new files plus the edits that wire them into the package. The marketplace takes that copy and drops it in a queue. A real person opens it like any other PR. They read the code, run your test, and either merge you into the catalog or send back notes.
This is the lesson where the loop closes. You started this course by pulling other people's components into your project. Now your component goes the other way. It goes into the catalog every member browses. And you can follow the whole trip from your terminal.

What inject sends to the marketplace
The last lesson left Magnet in the exact marketplace folder shape: Magnet.ts, its test, and a meta.json. Inject does not repackage any of that. It reads the folder, works out where it belongs, and builds a payload — one bundle that carries everything the marketplace needs and nothing tied to your machine.
That payload is a handful of fields, and together they are exactly what crosses the wire. target is the package the last lesson's detect rule picked: arcade for a gameplay component, viz for a debug panel. componentNames is what you asked for. files is the source itself. patches are the registration edits that splice the component into the package. A version stamp records which CLI built it. And your meta.json rides along as the marketplace card. There is no filesystem path from your machine and no git remote — just those fields, serialized to JSON and sent as a single web request that posts them to the marketplace's submissions endpointA specific URL on a server that accepts requests — here, the marketplace address inject POSTs your submission to.. The server answers with a 201, its way of saying "accepted, created." That is why your source never moves. The bytes that travel are a snapshot, copied into a request body.
Because the submission is a copy, you can keep working on Magnet the instant you hit enter. The review queue holds a frozen version. Your editor holds the live one.
Dry-run before you submit
Before any real submit, run injectThe bjs command that reads your component folder, bundles it as a diff, and submits it to the marketplace for review. with --dry-run. It does everything up to the POST. It finds your files, resolves the target, and builds the plan. Then it stops and prints the plan:
That last summary line counts the very same files and patches the real submit would send — a dry runRunning inject with --dry-run, which prints the file-and-patch plan and submits nothing. and a live submit build the identical plan; only the POST is held back. Read the plan like a list of changes, line by line, top to bottom. Check that these are the files you meant to share, and that no scratch experiment snuck in. Check that the test is listed. If it is not, the folder is not shaped the way you think, and a curator will bounce it. Check that the target is the right package. A gameplay component headed for arcade is correct. One headed for viz, when you did not write a panel, means the detect rule read something you did not intend.
When the plan looks clean, drop the flag and send it for real:
A few flags cover the cases the default misses. Name two components that really depend on each other and they travel as one submission. They get reviewed and landed together. --source <path> points inject at a folder outside src/components/<Name>/, but only for the source files. Inject still reads meta.json from src/components/<Name>/meta.json no matter what --source says. So keep or copy the component's meta.json there, or the marketplace card rides along empty. --target arcade|viz lets you state the destination yourself when a dry run sends your work somewhere unexpected. --layer applies only to viz targets. --force affects the operator-side apply mode, not what bjs inject submits. Run bjs inject --help to see them all.
The submission id
A successful submit prints two things, and the rest of this lesson lives on the first one. Your terminal shows:
The id is your submission's name everywhere from now on. It names it in the terminal, on the site, and in a curator's queue. The status starts at pending. That means it is in the queue, waiting, and no curator has opened it yet. The URL is the same submission on the website, if you would rather watch it there. But you do not have to leave the terminal.
Tracking with bjs submissions
Everything you have ever injected lives under one command. Its three subcommands are the whole tracking surface: list, show, and withdraw.
Bare bjs submissions, with no subcommand, falls through to list. So it prints the table of everything you have sent:
The --status option filters that list to one state. bjs submissions list --status pending shows only what is still in flight. --limit raises the twenty-row default. --json lives on every subcommand, for piping instead of reading. For the full detail on one submission, hand show its id:
That adds the fields the table leaves out. It shows when it was last updated and which CLI version built it. Once a curator has written some, it also shows the reviewer notes.
The states a submission moves through
The status column is a state machine. A submission sits in exactly one state. Each state allows exactly one move:
| State | What it means | Your one move |
|---|---|---|
pending | In the queue, untouched | Withdraw it |
reviewing | A curator has it open | Wait for the result |
merged | Shipped into the catalog | Acquire it like any component |
rejected | Returned with notes | Fix, inject again |
withdrawn | You pulled it back | Inject a fresh one |

The state machine is not only a table in this lesson. The CLI enforces it. While a submission is pending, you can pull it back; the moment a curator starts reviewing, you can no longer withdraw it. bjs submissions withdraw puts two guards between you and a mistake. First it asks you to confirm — Withdraw submission 142? (y/N) — so you can't pull one by accident; pass -y to skip that prompt. Then the server has the final say. If the submission already moved past pending, the request comes back as a 409 conflict, and the CLI turns that into a plain-English line: Already in review or finalized — can't withdraw. A 409 is one of a few HTTP status codes the server can return here; an expired session shows up as 401 with a nudge to run bjs login, an unknown id as 404, each with its own one-line message. So withdrawal is for the bug you spot minutes after injecting. Withdraw, fix, and inject again. Once a curator is reading, you let the review play out.
Reading reviewer notes and resubmitting
Say Magnet comes back rejected. Run bjs submissions show 142. The detail view now carries the reviewer notes a curator wrote while running your code:
The specifics here come from earlier ECS and component courses (Vector3, per-frame allocation, _temp reuse). At this stage, what matters is the shape of the feedback, not every term in it. A rejection is not a final no. It is a short list: a couple of concrete fixes and a missing test, about an afternoon's work, with a clear invitation to resubmit. Make the fixes in your project and inject again. The copy in the queue is frozen, and your source never left. The new submission gets a new id and rejoins the queue with no penalty. Most components that merge take a round or two of this. Feedback from someone who actually ran your code is some of the most useful you will get.
What merged means
One morning the row has changed:
Merging awards credits. That is the same balance you spend to acquire catalog components, now flowing the other way. Show a merged submission and the CLI calls the credits out directly — a line like +40 credits earned 🎉 sits right at the top of the detail view.
And Magnet is in the catalog. Open bjs bbs into the component listings and it sits there beside components written by people who have done this for years. It carries the description from its meta.json, with a credit cost next to it. Somewhere down the line, a member you have never met browses that catalog and spends credits to acquire Magnet. Your source lands in their src/components/: the pure logic, your comments, and your test. There they start reshaping it for a game you will never see.
That is the whole loop you have walked across this course. You log in once, scaffold a project, dial into the catalog, and pull assets down. You eject and own component source, shape one of your own, and inject it back. Community code came into your project, and your code went out into the community. The marketplace you started browsing now has you in it.