neutron-scripts
Bun-run TypeScript scripts that turn an app source tree into a .neutron
archive. Apps invoke them from their own package scripts; they are not a runtime
dependency.
validate
Validates the app-root neutron.json against the closed schema, then applies
the semantic checks that raw JSON Schema cannot express: unique tile ids, safe
relative asset paths, function exposure, display metadata, dependencies,
capability composition, and connection-provider rules. The static Motoko policy
runs later in mopack, once the complete dependency graph is available, and is
rechecked by neutron-compiler at compile/install time.
mogen — manifest and type generation
mogen reads the annotated Motoko backend and rewrites two things: the
manifest's func map, and a generated type-alias block inside the module.
You annotate methods with a comment placed directly between public func and
the method name:
| Annotation | Result |
|---|---|
/*update*/ | An owner-authorized update method |
/*query*/ | An owner-authorized query method |
/*internal*/ | A private generated wrapper only |
/*internal:apps*/ | Private, but exported to declared app consumers |
/*query:unauthorized*/ | Kernel package only — ordinary apps are rejected |
From this:
public func /*update*/set_name(name : Text) : Text { … }
mogen writes the manifest entry and generates:
public type set_name_Input = (name : Text);
public type set_name_Output = Text;
Those aliases are what the generated actor wrapper consumes. Do not hand-edit
the func map or the generated block — regenerate them.
mogen also mirrors async* return types so the wrapper emits await*, and
reads the block comment inside a parameter list that requests compiler-injected
arguments such as caller or a paid handler's cycles value.
mopack — the Motoko dependency packer
This is the most consequential script. It walks the app entry module, every declared memory schema, and every migration edge as independent roots, using one shared dependency cache, and:
- resolves Mops package roots (ignoring
mo:primandmo:⛔); - follows package and relative imports transitively;
- strips comments and empty lines from each module;
- rewrites every import to a content hash;
- computes the SHA-256 of the final rewritten content;
- writes each module to
dist/mo/<hash>.mo, re-verifying that hashing the written content still equals the filename; - records final
entryhashes and schema source hashes indist/neutron.json; - creates or verifies the append-only
neutron.lock.json.
It also runs the static policy over every final module. For a non-kernel
package, prohibited findings in the entry, any transitive dependency, any memory
schema, or any migration root cause mopack to print the offending source and
throw. You cannot produce an ordinary package from dangerous code.
When the manifest id is kernel, findings are still computed but permitted —
that is the explicit operating-system exception.
:::note Schema identity vs. executable identity
A packaged memory schema carries two different hashes. hash is the
comment-stripped source before imports are rewritten, and it is the
immutable lineage identity. entry is the executable module after imports are
rewritten to content hashes. Upgrading a Motoko package changes the executable
entry without changing the schema's historical identity — the compiler still
checks the resulting stable types.
:::
method_schema
Produces dist/schema.json. It reads the generated Motoko input/output aliases,
reconstructs each non-internal logical method signature, and asks the public
icblast npm package to emit its input/output JSON Schemas.
This is a developer and package-inspection artifact only. It deliberately does not duplicate the generated physical Candid name, and it never authorizes binary positions or sizes. At runtime the kernel derives the trusted type from the live installed canister interface.
pack
Creates the archive:
- walks every file under
dist/(thedist/prefix is not stored); - gzips each file individually;
- MessagePack-encodes the flat path-to-bytes map;
- names the output from the manifest id and the semantic form of its packed version.
There is no outer archive directory and no outer gzip layer. See Package format.
compile_motoko
Compiles an actor with Neutron's exact vendored Motoko WebAssembly compiler and
emits the matching Candid sidecar (optionally the stable-types sidecar too). It
invokes Mops only to resolve package roots and never resolves or executes a
moc found on the shell PATH. An unrelated Motoko installation on your
machine is not part of any Neutron build.
whitelist_create
Regenerates the reviewed content-hash exception list. It resolves the installed
mo:core root and considers only the exact final files for Principal.mo and
Runtime.mo, refusing every other Core module — including Random.mo,
Cycles.mo, InternetComputer.mo, Region.mo, and Timer.mo. See
Static checks.