Skip to main content

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:

AnnotationResult
/*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:

  1. resolves Mops package roots (ignoring mo:prim and mo:⛔);
  2. follows package and relative imports transitively;
  3. strips comments and empty lines from each module;
  4. rewrites every import to a content hash;
  5. computes the SHA-256 of the final rewritten content;
  6. writes each module to dist/mo/<hash>.mo, re-verifying that hashing the written content still equals the filename;
  7. records final entry hashes and schema source hashes in dist/neutron.json;
  8. 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/ (the dist/ 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.