Skip to content

Quickstart

This walks from an empty crate to a method call. The two binaries you use are merod (the node daemon — init, run) and meroctl (the operator CLI — app, context, namespace, call).

  1. Scaffold an app with the cargo mero toolchain:

    Terminal window
    cargo mero new my-app
    cd my-app

    This writes a ready-to-build crate: Cargo.toml (SDK pins, the app-id metadata, and the build profiles), a working src/lib.rs, and a TestHost test. The tutorial walks the generated manifest field by field.

  2. The generated src/lib.rs is already a working app: a state struct plus methods. This is the shape every Calimero app follows (see SDK macros):

    use calimero_sdk::app;
    use calimero_storage::collections::{LwwRegister, UnorderedMap};
    #[app::state]
    pub struct KvStore {
    items: UnorderedMap<String, LwwRegister<String>>,
    }
    #[app::logic]
    impl KvStore {
    #[app::init]
    pub fn init() -> KvStore {
    KvStore { items: UnorderedMap::new() }
    }
    pub fn set(&mut self, key: String, value: String) -> app::Result<()> {
    self.items.insert(key, value.into())?;
    Ok(())
    }
    #[app::view]
    pub fn get(&self, key: String) -> app::Result<Option<String>> {
    Ok(self.items.get(&key)?.map(|v| v.get().clone()))
    }
    }
  3. Build to WASM with the cargo mero toolchain:

    Terminal window
    cargo mero build

    One command compiles, optimizes, and embeds the ABI; the wasm lands at res/<crate_name>.wasm, ready to bundle.

  1. Initialize a node’s config and data directory, then run it:

    Terminal window
    merod --node node1 init --server-port 2428 --swarm-port 2528
    merod --node node1 run

    merod --node node1 init --help lists the full set (swarm/server host and port, boot nodes, mDNS, auth mode). Config and data live under CALIMERO_HOME / --home.

3. Install the app, attach a context, call a method

Section titled “3. Install the app, attach a context, call a method”

meroctl talks to a running node. Select the node with --node node1 (a configured alias) or --api <URL>.

  1. Install the WASM module. The node returns an application id:

    Terminal window
    meroctl --node node1 app install \
    --path ./res/my_app.wasm \
    --package com.example.myapp \
    --version 1.0.0

    List what is installed with meroctl --node node1 app ls.

    Installing the raw wasm is the fast dev loop; for a signed, distributable .mpk run cargo mero bundle and pass the bundle to --path instead - see Packaging & signing.

  2. Attach the app to a context. A context is a running instance of an app over a shared state. The simplest entry is to create a namespace bound to the application id:

    Terminal window
    meroctl --node node1 namespace create --application-id <app-id>
  3. Call a method on the context. Mutations and views both go through the top-level call command — whether a call mutates or is a read-only view is decided by the method’s own #[app::view] marker, not a CLI flag:

    Terminal window
    # mutate
    meroctl --node node1 call set \
    --context <context-id> \
    --args '{"key": "hello", "value": "world"}'
    # view
    meroctl --node node1 call get \
    --context <context-id> \
    --args '{"key": "hello"}'

    --args takes JSON matching the method’s parameters. <context-id> accepts a context id or an alias you created with --name.

These three commands trace one path from a built artifact to a method result — install the code, attach a context over shared state, then call into it: