Skip to main content
Version: 3.x (unreleased)

mops.toml file

All relative paths in mops.toml are resolved relative to the directory containing the file. This applies to canister entrypoints, candid paths, local dependencies, build output directories, moc flags with path arguments, and any other path-valued setting.

[package]

FieldDescription
namePackage name (e.g. lib)
versionPackage version in format x.y.z (e.g. 0.1.2)
descriptionPackage description shown in search results
repositoryRepository url (e.g. https://github.com/caffeinelabs/motoko-base).
Can include subdirs (see note below)
keywordsArray of keywords (max 10 items, max 20 chars)
licensePackage license. Use SPDX license identifier (e.g. MIT)
filesArray of glob patterns for files to include when publishing (default ["**/*.mo"])
baseDirBase directory for package sources (default src). Used by mops sources to resolve the package entrypoint
readmePath to README file (default README.md)
note

Repository URL can include subdirectory when the package is located not in the root of the repository.

Example for vetkeys package https://github.com/dfinity/vetkeys/tree/main/backend/mo/ic_vetkeys

repository = "https://github.com/dfinity/vetkeys/backend/mo/ic_vetkeys"

Make sure there is no /tree/main/ in the URL.

[dependencies]

FieldDescription
<mops_package_name>
Example: base
Version in format x.y.z (e.g. 0.1.2)
<mops_package_name>@<pinned_version>
Example: base@0.11.0
Version in format x.y.z (e.g. 0.1.2)
<local_package_name>
Example: shared
Local path starting with ./, ../, or /
Example: ./packages/shared
note

GitHub dependencies are not allowed in [dependencies]. Please publish the dependency to the Mops registry instead.

Learn how Mops resolves dependencies here.

Learn about version pinning here.

[dev-dependencies]

Same structure as [dependencies], with the exception that GitHub dependencies are allowed.

dev-dependencies are only used for testing and benchmarking purposes. They are not installed when the package is used as a dependency.

[toolchain]

See toolchain management page for more details.

FieldDescription
mocMotoko compiler version (e.g. 1.0.0) or file path (e.g. ./tools/moc, /usr/local/bin/moc)
wasmtimeWASM runtime version (e.g. 41.0.0) or file path used to run tests in wasi mode
pocket-icPocketIC replica version (e.g. 14.0.0) or file path, used to run benchmarks and replica tests. Optional — with no pin Mops uses a default version. Versions below 9.0.0 are no longer supported. See pocket-ic versions
lintokoLinter version (e.g. 0.7.0) or file path for Motoko linting
wasm-optBinaryen version (e.g. 131) or file path used for [optimize] post-build Wasm optimization

File paths must start with /, ./, or ../.

[moc]

Global Motoko compiler flags applied to all moc invocations (check, check-stable, build, test, bench, watch).

FieldDescription
argsArray of flags to pass to moc (e.g. ["--default-persistent-actors", "-Werror"])

Example:

[moc]
args = ["--default-persistent-actors", "-W=M0223,M0236,M0237"]

These flags are applied before per-canister [canisters.<name>].args and CLI -- flags. For mops build, [build].args are also applied (after [moc].args, before per-canister args).

Use mops moc-args to print the moc flags defined in mops.toml (useful when invoking moc directly).

[canisters]

Define Motoko canisters for mops build, mops check, and mops check-stable.

Each canister entry specifies the entrypoint file and optional compiler settings.

FieldDescription
mainPath to the main Motoko file (required)
argsArray of additional moc arguments for this canister (optional). Applied after [moc].args in check, check-stable, and build.
candidPath to a Candid interface file (optional). mops build subtype-checks the generated interface against this file and embeds it into the wasm as candid:service metadata. mops generate candid writes the regenerated .did to this path.
initArgCandid-encoded initialization arguments (optional)
wasmMemoryLimitPositive integer Wasm memory limit in bytes applied by mops build --check-deploy (optional). Invalid values are rejected by every command that resolves canisters.

Example:

[canisters.backend]
main = "src/main.mo"
args = ["--incremental-gc"]
candid = "candid/backend.did"
initArg = "(\"Hello\")"

Multi-canister example with per-canister flags:

[canisters.backend]
main = "src/backend/main.mo"

[canisters.backend.migrations]
chain = "src/backend/migrations"

[canisters.frontend]
main = "src/frontend/main.mo"

[canisters.<name>.check-stable]

Configure automatic stable variable compatibility checking for a canister. When set, mops check will verify that the current canister is compatible with the deployed version.

FieldDescription
pathPath to the deployed version's .most or .mo file (required). A .most file is preferred; when a .mo file is provided, stable types are generated from it (the file must compile successfully)

Example:

[canisters.backend.check-stable]
path = "deployed/backend.most"

For a new project with no prior deployment, run mops deployed init — it commits an empty-actor .most at the configured path so the check passes against an empty baseline. After every successful deploy, run mops deployed to promote the just-built .most into this file.

[canisters.<name>.migrations]

Configure managed enhanced migration chains for a canister. When set, mops check, mops build, and mops check-stable auto-inject --enhanced-migration for the canister. Create migration files directly in the chain directory.

After mops check --fix (or mops check <canister>) confirms the chain compiles, run mops build to produce the wasm artifact.

FieldDescription
chainPath to the directory containing migration files (required)
check-limitMax number of recent migrations to pass to moc during mops check and mops check-stable, and to lintoko during mops lint (optional). Useful when the chain grows long and re-checking every old migration slows feedback down. When set, the stable check reports if more migrations are pending (relative to the deployed .most baseline) than the limit allows — as an error if compat failed, otherwise a warning. Override per run with --no-check-limit
nextPath to the directory for a pending migration (optional, experimental). Required for the experimental mops migrate workflow. Must contain 0 or 1 .mo files. Must share the same parent directory as chain
build-limitMax number of recent migrations to pass to moc during mops build (optional, experimental)

Example:

[canisters.backend.migrations]
chain = "migrations"
check-limit = 10

Migration files must be named so they sort lexicographically in the correct order. The recommended naming convention is YYYYMMDD_HHMMSS_Name.mo (e.g. 20250415_120000_AddEmail.mo).

note

When [migrations] is configured, do not add --enhanced-migration to [canisters.<name>].args — mops manages this flag automatically.

note

When chain trimming is active (or a next migration is configured), mops stages the active chain into <parent-of-chain>/.migrations-<canister>/ for compilation. This keeps the staged files at the same depth as the originals so relative imports (e.g. a shared types/ folder next to the chain) resolve identically. The staged dir self-stamps a .gitignore, and mops init adds .migrations-*/ to the project .gitignore.

moc diagnostics may point to a staged path under .migrations-<canister>/, which mops removes when the command finishes.

Shorthand — when only the entrypoint is needed:

[canisters]
backend = "src/main.mo"

[build]

Global build settings used by mops build.

FieldDescription
outputDirOutput directory for compiled Wasm and Candid files (default .mops/.build). Path is relative to mops.toml. The --output CLI flag takes precedence.
argsArray of flags passed to moc for every canister build (e.g. ["--release", "--ai-errors"])
check-wasmAnalyze each final Wasm for likely IC0505 function-complexity risks without starting PocketIC (default false). Override for one build with --check-wasm or --no-check-wasm.
check-deployInstall every built Wasm on a fresh PocketIC canister and fail on deployment or initialization errors (default false). Runs on the pinned [toolchain] pocket-ic, or the default version when unpinned; pins below 9.0.0 are rejected. Before installation, Mops runs moc --stable-compatible from a temporary empty-actor .most to each generated .most. Incompatible canisters are skipped with MOPS-CHECK-DEPLOY-SKIPPED; eligible siblings are still checked. Override for one build with --check-deploy or --no-check-deploy.

Example:

[build]
outputDir = "dist"
args = ["--release", "--ai-errors"]
check-wasm = true
check-deploy = true

These flags are applied after [moc].args and before per-canister [canisters.<name>].args.

[optimize]

Opt-in post-build Wasm optimization via Binaryen's wasm-opt. When this section is present (even empty), mops build and mops bench run wasm-opt on the compiled module after candid metadata is attached.

FieldDescription
levelOptimization level: O0, O1, O2, O3 (default), O4, Os, or Oz
keep-namesKeep the Wasm name section for readable backtraces (default true, maps to wasm-opt -g)
argsExtra flags passed to wasm-opt (optional)

Example — enable with defaults (O3, keep names):

[optimize]

Example — size-oriented, strip names, extra flag:

[optimize]
level = "Oz"
keep-names = false
args = ["--enable-bulk-memory"]

Pin Binaryen via [toolchain] wasm-opt (e.g. "131"). If [optimize] is set and wasm-opt is not pinned, mops auto-pins the latest Binaryen release into mops.toml on the next build/bench (rewrites the file like mops add — prefer pinning explicitly in CI).

If wasm-opt fails, mops warns and keeps the unoptimized Wasm (same soft-fail behavior as dfx). Use --verbose for full wasm-opt output.

Pass --no-optimize to mops build or mops bench to skip this pass for a single run without editing mops.toml.

note

Deploy recipes (e.g. icp-cli) that also run wasm-opt should skip that step when mops already optimized the artifact — avoid stacking passes. Actor-class Wasm embedded inside Motoko modules is not recursively optimized.

[deployed]

Settings for mops deployed.

FieldDescription
dirDirectory where mops deployed writes promoted .most files (default deployed). Path is relative to mops.toml. Override per invocation with --dir.

Example:

[deployed]
dir = "deployed"

All canisters share one directory; per-canister overrides are not supported.

[lint]

Settings for mops lint.

FieldDescription
argsArray of extra flags passed to lintoko (e.g. ["--severity", "warning"])
rulesArray of local rule directory paths to use (e.g. ["lint"]). Overrides the default lint//lints/ directories when set.
extendsPull in rules/ directories from installed dependencies. Set to true to include all dependencies that ship rules, or to an array of package names (e.g. ["pkg"]) to be selective.

Example:

[lint]
args = ["--severity", "warning"]
rules = ["my-rules"]
extends = ["some-pkg"]

[lint.extra]

Map file globs to additional rule directories. Each entry runs a separate lintoko invocation on the matched files, in addition to the base rules that always apply to all files.

Key (glob)Value (string array)
File globArray of rule directory paths to apply

Example:

[lint.extra]
"src/main.mo" = ["lint/no-types"]
"src/Types.mo" = ["lint/types-only"]
"migrations/*.mo" = ["lint/migration-only", "lint/no-types"]

Globs that match no files are skipped with a warning. All runs (base and extra) execute even when earlier runs find errors, so you see every failure in a single pass. The --rules CLI flag does not affect [lint.extra] entries.

[requirements]

When a user installs your package(as a transitive dependency too), Mops will check if the requirements are met and display a warning if they are not.

Use when your package will not work with older versions of the moc compiler or lintoko linter (e.g. rules that depend on lintoko features from a specific release).

FieldDescription
mocMotoko compiler version (e.g. 0.11.0 which means >=0.11.0)
lintokoLintoko linter version (e.g. 0.10.0 which means >=0.10.0)

Advanced Configuration

For additional configuration options including registry endpoint overrides, see Environment Variables.