Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .sources/VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ chain-fusion-signer v0.3.0
papi v0.1.1 168bc9d
ic-pub-key v1.0.1 f89fa55
icp-cli v0.2.3 caeac37
motoko v1.8.0 75c4123
motoko v1.8.2 f45204b
motoko-core v2.4.0 cd37dbf
cdk-rs ic-cdk v0.20.1 / ic-cdk-timers v1.0.0 / ic-cdk-executor v2.0.0 317f55c
candid 2025-12-18 # candid v0.10.20, didc v0.5.4 2e4a2cf
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ A cleaner, more maintainable solution, is to declare an explicit migration expre
Both of these data migration paths are supported by static and dynamic checks that prevent data loss or corruption. A user may still lose data due to coding errors, so should tread carefully.

For more information, see the [example of explicit migration](./compatibility.md#explicit-migration-using-a-migration-function) and the
reference material on [migration expressions](../../reference/language-manual.md#migration-expressions).
reference material on [migration expressions](../../language-manual.md#migration-expressions).

## Legacy features

Expand Down
3 changes: 0 additions & 3 deletions docs/languages/motoko/fundamentals/actors/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Actors"
description: "Actors are Motoko's unit of state and asynchronous concurrency. Each canister is an actor with private state and a public, async-only interface."
sidebar:
order: 3
label: "Actors"
hidden: true
---

Actors are Motoko's unit of state and asynchronous concurrency. Each canister is an actor: it has private state and a public interface composed of asynchronous methods. This section covers the actor model, messaging, persistence across upgrades, and migration patterns.
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Orthogonal persistence"
description: "How Motoko preserves the entire program state across canister upgrades, with no database layer or serialization code."
sidebar:
order: 6
label: "Orthogonal persistence"
hidden: true
---

Orthogonal persistence is the mechanism by which Motoko preserves an actor's state across canister upgrades automatically: no database, no stable memory API, no serialization code. This section covers the classical and enhanced persistence models and the trade-offs between them.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Multi-line comments can be nested within each other.

## Resources

- [Comment style guide](../../reference/style-guide.md#comments)
- [Comment style guide](../../style-guide.md#comments)

- [Generating Motoko documentation](/developer-tools/#mo-doc)

Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ let snake_case_identifier = "for compatibility with other languages";

## Reserved syntax keywords

Motoko reserves [keywords](../../reference/language-manual.md#keywords) for its syntax and they cannot be used as identifiers.
Motoko reserves [keywords](../../language-manual.md#keywords) for its syntax and they cannot be used as identifiers.
3 changes: 0 additions & 3 deletions docs/languages/motoko/fundamentals/basic-syntax/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Basic syntax"
description: "The lexical and surface syntax of Motoko: identifiers, literals, operators, functions, comments, and the structure of an actor."
sidebar:
order: 2
label: "Basic syntax"
hidden: true
---

This section covers the lexical and surface syntax of Motoko: how to define an actor, write functions, declare identifiers, use literals and operators, and the conventions for comments and whitespace.
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ You can use literals directly in expressions.

## Resources

- [Literals](../../reference/language-manual.md#literals)
- [Literals](../../language-manual.md#literals)

Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ persistent actor Counter {

## Resources

- [Motoko style guide](../../reference/style-guide.md)
- [Motoko style guide](../../style-guide.md)

3 changes: 0 additions & 3 deletions docs/languages/motoko/fundamentals/control-flow/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Control flow"
description: "Motoko's control flow constructs: blocks, conditionals, switch expressions, loops, and the expression-oriented evaluation model."
sidebar:
order: 6
label: "Control flow"
hidden: true
---

Control flow in Motoko is expression-oriented: blocks, conditionals, `switch`, and loops are all expressions that evaluate to a value. This section covers each construct and the patterns that compose them.
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,5 @@ Using this `system` syntax, developers can:
- Manually install, upgrade, or reinstall canisters.
- Access lower-level canister management features provided by ICP.

[Learn more about actor class management](../../reference/language-manual.md#actor-class-management).
[Learn more about actor class management](../../language-manual.md#actor-class-management).

3 changes: 0 additions & 3 deletions docs/languages/motoko/fundamentals/declarations/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Declarations"
description: "Motoko's declaration forms: variables, types, functions, classes, modules, and objects."
sidebar:
order: 5
label: "Declarations"
hidden: true
---

Declarations introduce names into a Motoko program. This section covers the full set of declaration forms: variable and type bindings, functions, classes, modules, and object literals, including the rules around scope and recursion.
3 changes: 0 additions & 3 deletions docs/languages/motoko/fundamentals/types/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
---
title: "Types"
description: "Motoko's type system: primitive types, records, tuples, variants, options, results, arrays, function types, and subtyping."
sidebar:
order: 4
label: "Types"
hidden: true
---

Motoko has a sound, expressive type system that prevents whole classes of bugs at compile time: null-pointer errors, missing-pattern errors, and uncoordinated stable-state changes across upgrades. This section covers each type form and the subtyping rules that connect them.
44 changes: 32 additions & 12 deletions docs/languages/motoko/icp-features/system-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,35 +49,55 @@ system func timer(setGlobalTimer : Nat64 -> ()) : async () {

## `preupgrade()`

The `preupgrade()` system function is invoked immediately before a canister upgrade. It runs before the new Wasm module is installed, giving the current version one last chance to act. The function takes no arguments and must have type `() -> ()`.
The preupgrade() system function is invoked immediately before a canister upgrade to prepare for state migration. Its primary role is to save critical data, typically non-stable variables, into stable storage, ensuring that important state information is preserved across the upgrade. This function executes before the new Wasm module is installed, making it the last opportunity to capture any necessary state from the current canister version.

Any failure, such as a trap or exceeding computation limits prevents the upgrade from succeeding, potentially leaving the canister in an unrecoverable state. As a result, **using `preupgrade()` is discouraged unless necessary**.

The following example saves a `HashMap` of user balances into a stable variable before upgrading.

`balances` is a non-stable `HashMap` that would normally be lost during an upgrade. Before upgrading, `preupgrade()` stores the key-value pairs in a stable array (`savedBalances`).

After upgrading, the `postupgrade()` function (#postupgrade) can restore the saved state.

```motoko no-repl
persistent actor MyCanister {
import Iter "mo:core/Iter";
import HashMap "mo:base/HashMap"; // Data structure from original standard library

persistent actor Token {

transient var balances = HashMap.HashMap<Text, Nat>(10, Text.equal, Text.hash); // Non-stable
var savedBalances : [(Text, Nat)] = []; // Implicit stable storage

system func preupgrade() {
// Runs before the upgrade installs the new Wasm.
savedBalances := Iter.toArray(balances.entries()); // Save state before upgrade
}
}
```

:::danger
If `preupgrade` traps, runs out of cycles, or hits any other IC computing limit, **the upgrade fails and the canister cannot be upgraded going forward**: it is stuck on the current version. Use of this hook is discouraged.
:::

With orthogonal persistence, `mo:core` data structures persist across upgrades automatically and this hook is rarely needed. For the (legacy) save-into-stable-storage pattern and the migration alternatives that replace it, see [Data persistence](../fundamentals/actors/data-persistence.md).

## `postupgrade()`

The `postupgrade()` system function runs immediately after an upgrade installs the new Wasm. The function takes no arguments and must have type `() -> ()`.
The `postupgrade()` system function is called immediately after a canister upgrade, allowing a canister to restore state or execute initialization logic. Unlike `preupgrade()`, **it is not required**, as most of its effects can be achieved using actor initialization expressions (`let` bindings and expression statements). However, `postupgrade()` is useful for reconstructing data structures or running migration logic.

This example restores the `balances` `HashMap` using the data that was saved by `preupgrade()`.

```motoko no-repl
persistent actor MyCanister {
import HashMap "mo:base/HashMap"; // Data structure from original standard library

persistent actor Token {

transient var balances = HashMap.HashMap<Text, Nat>(10, Text.equal, Text.hash);
var savedBalances : [(Text, Nat)] = [];

system func postupgrade() {
// Runs after the upgrade installs the new Wasm.
balances := HashMap.fromIter(savedBalances.vals(), 10, Text.equal, Text.hash);
}
}
```

`postupgrade` is rarely required: the same effect can usually be achieved with actor initialization expressions (`let` bindings and statements at the top of the actor body), which run on every install and upgrade. See [Data persistence](../fundamentals/actors/data-persistence.md) for the recommended patterns.
The **use of upgrade hooks is not recommended** as they can fail and cause the program to enter an unrecoverable state. With advancements in orthogonal persistence, these hooks are expected to be deprecated.

In many cases, stable variables or actor initialization expressions can replace `postupgrade()`. Complex transformations increase the risk of errors and failures.

## `lowmemory()`

Expand Down
23 changes: 0 additions & 23 deletions docs/languages/motoko/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,6 @@ If you have an existing project using `base`, you can migrate incrementally; bot

`core` and all other Motoko packages are managed with [Mops](https://mops.one), which handles dependency resolution, compiler toolchain management, and publishing. Browse community packages at [mops.one](https://mops.one).

## Example projects

Starting points by use case:

**Web applications**

- [Hello, world!](https://github.com/dfinity/examples/tree/master/motoko/hello_world)
- [Calling external APIs from a Motoko canister](https://github.com/dfinity/examples/tree/master/motoko/send_http_get)
- [Reversi game](https://github.com/ninegua/reversi)

**DeFi**

- [ICRC-1 token canister](https://github.com/sonicdex/icrc-1-public/)
- [Decentralized exchange (DEX)](https://github.com/dfinity/examples/tree/master/motoko/icrc2-swap)
- [ICRC-7 NFTs](https://github.com/noku-team/icrc7_motoko)

**Chain Fusion**

- [Ethereum integration](https://github.com/dfinity/icp-eth-starter)
- [Bitcoin point-of-sale](https://github.com/dfinity/examples/tree/master/motoko/ic-pos)

For more, browse the full [Motoko examples collection](https://github.com/dfinity/examples/tree/master/motoko).

## Further reading

- [Quickstart](/getting-started/quickstart): create and deploy your first canister
Expand Down
2 changes: 1 addition & 1 deletion docs/languages/motoko/reference/compiler-ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ You can use the following options with the `moc` command.
| `--incremental-gc` | Use incremental GC (default, works with both enhanced orthogonal persistence and legacy/classical persistence). |
| `--idl` | Compile binary and emit Candid IDL specification to `.did` file. |
| `-i` | Runs the compiler in an interactive read–eval–print loop (REPL) shell so you can evaluate program execution (implies -r). |
| `--implicit-derivation-depth <n>` | Maximum recursion depth for [implicit](../fundamentals/implicit-parameters.md) argument derivation (default 100). Raise if a complex derivation is rejected as depth-limited. |
| `--implicit-derivation-depth <n>` | Maximum recursion depth for [implicit](./fundamentals/11-implicit-parameters.md) argument derivation (default 100). Raise if a complex derivation is rejected as depth-limited. |
| `--legacy-persistence` | Use legacy (classical) persistence. This also enables the usage of --copying-gc, --compacting-gc, and --generational-gc. Deprecated in favor of the new enhanced orthogonal persistence, which is default. Legacy persistence will be removed in the future.|
| `--map` | Outputs a JavaScript source map. |
| `--max-stable-pages <n>` | Set maximum number of pages available for library `ExperimentStableMemory.mo` (default 65536). |
Expand Down
Loading