Skip to content

docs: deprecate init_module, document explicit initialize pattern#477

Open
gregnazario wants to merge 8 commits into
mainfrom
claude/infallible-blackburn-03416e
Open

docs: deprecate init_module, document explicit initialize pattern#477
gregnazario wants to merge 8 commits into
mainfrom
claude/infallible-blackburn-03416e

Conversation

@gregnazario

Copy link
Copy Markdown
Collaborator

Summary

Deprecates the Move init_module function across the docs and steers readers to a guarded public entry fun initialize pattern. init_module is being removed because it causes issues in the VM.

Changes

  • Canonical reference (modules-on-aptos.mdx EN+ZH): deprecation banner + a new "Recommended: explicit initialize entry function" section documenting the replacement with both guards (publisher-address authorization assert + !exists<> once-guard) and the separate-transaction operational caveat.
  • Solidity→Move comparison guides (billboard module-initialization.mdx, dutch-auction initialization.mdx, both EN+ZH): init_module fully scrubbed and replaced with initialize; frontmatter descriptions and prose updated. The dutch-auction sample uses the guide's existing error::permission_denied(ENOT_OWNER) convention.
  • Tutorials (first-coin.mdx, first-fungible-asset.mdx, EN only): deprecation callouts added. Their init_module code samples are intentionally kept because they mirror runnable examples in aptos-labs/aptos-core (moon_coin.move, fa_coin.move) — see follow-ups.

Replacement pattern

public entry fun initialize(publisher: &signer) {
    assert!(signer::address_of(publisher) == @my_addr, error::permission_denied(ENOT_AUTHORIZED));
    assert!(!exists<ModuleData>(@my_addr), error::already_exists(EALREADY_INITIALIZED));
    move_to(publisher, ModuleData { /* ... */ });
}

The two guards recover the once-only and publisher-only guarantees that init_module provided automatically.

Verification

  • pnpm lint clean; pnpm check 0 errors / 0 warnings (2 pre-existing unrelated hints)
  • pnpm test tests/agent-discovery.test.ts tests/markdown-negotiation.test.ts → 42/42 pass
  • Pre-push hook: astro check, full build, and link validation all green
  • Audit: init_module now appears only in the reference (as legacy/deprecated) and the two tutorials (samples + callouts); both ethereum-to-aptos guides are fully scrubbed

Follow-ups (out of scope, noted in the plan)

  • aptos-core companion PR: once moon_coin.move / fa_coin.move migrate to initialize, swap the tutorial samples and drop the "will be updated once that example is migrated" line from both callouts.
  • Reference link: add an AIP/reference link to the deprecation callouts once one is public.

Note

This branch also contains the design spec and implementation plan under docs/superpowers/ (commits e0c4253, 9c3f55d). If you don't want those planning artifacts in the repo, I can drop those two commits before merge.

@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aptos-docs Ready Ready Preview, Comment Jul 13, 2026 7:40pm

Request Review


- Solidity declares contracts with the `contract` keyword. Move declares modules as `address::module_name`.
- Solidity constructors run once at deployment. Move initialization logic typically lives in `init_module`.
- Solidity constructors run once at deployment. In Move, run initialization logic from an explicit `public entry fun initialize` that the publisher calls after publishing (see [Modules on Aptos](/build/smart-contracts/modules-on-aptos#recommended-explicit-initialize-entry-function)).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would say, "In move, initialization is an explicit action invoked by developer, giving them more control. An explicit public entry fun initialize needs to be called..."

basically adding some motivation that explicit init is not too bad: it gives you control on the order of initialization, and aligns with decoupled code-data paradigm in Move.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit2:
No need for public, let's use entry fun initialize

The MoonCoin module defines the `MoonCoin` struct, or the distinct type of coin type. In addition, it contains a function called `init_module`. The `init_module` function is called when the module is published. In this case, MoonCoin initializes the `MoonCoin` coin type as a `ManagedCoin`, which is maintained by the owner of the account.

<Aside type="danger" title="`init_module` is deprecated">
`init_module` is deprecated and being removed because it causes issues in the VM. New modules should initialize state with an explicit `public entry fun initialize` called by the publisher after publishing — see [Modules on Aptos](/build/smart-contracts/modules-on-aptos#recommended-explicit-initialize-entry-function). This example still uses `init_module` to match the on-chain example module; it will be updated once that example is migrated.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it has no ordering semantics which inits run first? "Adds complexity for the VM"?

The `ManagedFungibleAsset` standard helps keep track of which permissions this Module is allowed to use.

<Aside type="danger" title="`init_module` is deprecated">
`init_module` is deprecated and being removed because it causes issues in the VM. New modules should initialize state with an explicit `public entry fun initialize` called by the publisher after publishing — see [Modules on Aptos](/build/smart-contracts/modules-on-aptos#recommended-explicit-initialize-entry-function). This example still uses `init_module` to match the on-chain example module; it will be updated once that example is migrated.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for src/content/docs/build/guides/first-coin.mdx

- Create resource accounts or other module-specific setup tasks

<Aside type="danger" title="`init_module` is deprecated">
The `init_module` function is **deprecated** and is being removed because it causes issues in the VM. Do not use it in new modules. Initialize modules with an explicit `public entry fun initialize` that the publisher calls after publishing the package (see below).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we list more reasons here:

  • No clear linking semantics (old or new code?)
  • No initialization order
  • Adds significant complexity to the VM

- Remove `public` from `entry fun initialize` throughout (entry fun is
  sufficient; the publisher calls it via a transaction, not from another
  module)
- Expand init_module deprecation rationale with specific reasons: no
  clear linking semantics, no initialization order, adds VM complexity
- Rephrase billboard guide bullet to convey that explicit initialization
  is a feature — gives developer control over init order and aligns with
  Move's code/data separation paradigm
- Sync all changes to zh translations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants