Problem
Motoko entry points are inconsistent with the rest of the ecosystem, and the name app.mo is arbitrary for many examples. Current census (tracked files):
- 34 examples use
backend/app.mo (or <role>/app.mo in multi-canister examples, e.g. parallel_calls/caller/app.mo)
- 1 example (
motoko/who_am_i, the legacy-layout II reference example) already uses main.mo
Recommendation: rename to main.mo (lowercase), not Main.mo
Main.mo (PascalCase) was considered for consistency with the repo's module-file convention (Counter.mo, Types.mo), but every official source of truth uses lowercase main.mo:
| Source |
Entry file |
icp-cli-templates (motoko template, icp new) |
src/main.mo |
icp-cli-templates (hello-world/motoko-backend) |
src/main.mo |
mops docs/skill ([canisters] snippets) |
main.mo |
Motoko skill architecture (types.mo / lib/ / main.mo) |
main.mo |
| Caffeine project layout |
main.mo |
motoko/who_am_i in this repo |
main.mo |
A developer graduating from icp new to these examples should see the same filename. The PascalCase convention applies to importable modules named after the type they export; the entry point is a composition root, not an imported module, and the ecosystem treats it as the special lowercase main.mo (analogous to lib.rs/main.rs in Rust — which our Rust examples already follow).
Migration scope
git mv backend/app.mo backend/main.mo in 34 examples (incl. <role>/app.mo in parallel_calls, pub-sub, etc.)
- Update
main = "backend/app.mo" in each mops.toml [canisters.*] section
- Update AGENTS.md: canonical structure tree, mops.toml snippet, and the naming-conventions bullet ("Entry point file: always
backend/app.mo")
- Sweep READMEs/scripts for literal
app.mo references
- No CI changes needed (paths resolve via
mops.toml); ICP Ninja sync picks up the rename via the normal mirror
Mechanical, single-PR-able, and zero behavioral risk (mops check across all examples verifies).
Problem
Motoko entry points are inconsistent with the rest of the ecosystem, and the name
app.mois arbitrary for many examples. Current census (tracked files):backend/app.mo(or<role>/app.moin multi-canister examples, e.g.parallel_calls/caller/app.mo)motoko/who_am_i, the legacy-layout II reference example) already usesmain.moRecommendation: rename to
main.mo(lowercase), notMain.moMain.mo(PascalCase) was considered for consistency with the repo's module-file convention (Counter.mo,Types.mo), but every official source of truth uses lowercasemain.mo:icp-cli-templates(motoko template,icp new)src/main.moicp-cli-templates(hello-world/motoko-backend)src/main.mo[canisters]snippets)main.motypes.mo/lib//main.mo)main.momain.momotoko/who_am_iin this repomain.moA developer graduating from
icp newto these examples should see the same filename. The PascalCase convention applies to importable modules named after the type they export; the entry point is a composition root, not an imported module, and the ecosystem treats it as the special lowercasemain.mo(analogous tolib.rs/main.rsin Rust — which our Rust examples already follow).Migration scope
git mv backend/app.mo backend/main.moin 34 examples (incl.<role>/app.moinparallel_calls,pub-sub, etc.)main = "backend/app.mo"in eachmops.toml[canisters.*]sectionbackend/app.mo")app.moreferencesmops.toml); ICP Ninja sync picks up the rename via the normal mirrorMechanical, single-PR-able, and zero behavioral risk (
mops checkacross all examples verifies).