Skip to main content
Version: 0.14 (unstable)

Custom Types

When public component methods use custom structs or enums, those types must be annotated with #[export_type] so the compiler can include them in the component's public API. Types used only internally (in private methods or local variables) don't need this annotation.

If you forget #[export_type] on a public API type, the compiler will emit an error telling you to add it.

Exporting structs

Struct fields must be public and use types that are either SDK types (Felt, Word, Asset, etc.) or themselves marked with #[export_type]:

use miden::{export_type, Felt, Word, Asset, component};

#[export_type]
pub struct StructA {
pub foo: Word,
pub asset: Asset,
}

#[export_type]
pub struct StructB {
pub bar: Felt,
pub baz: Felt,
}

#[component]
struct MyAccount;

#[component]
impl MyAccount {
pub fn process(&self, a: StructA, asset: Asset) -> StructB {
StructB {
bar: a.foo[0],
baz: a.foo[1],
}
}
}

Exporting enums

Enums use the same annotation. Enum variants can be unit variants:

use miden::{export_type, Felt};

#[export_type]
pub enum Status {
Active,
Inactive,
}

Nested types

Exported types can reference other exported types:

#[export_type]
pub struct Inner {
pub value: Felt,
}

#[export_type]
pub struct Outer {
pub nested: Inner,
}

The compiler resolves references regardless of declaration order.

Types in submodules

Custom types can be defined in submodules. Each type still needs #[export_type]:

pub mod my_types {
use miden::{Felt, export_type};

#[export_type]
pub struct StructC {
pub inner1: Felt,
pub inner2: Felt,
}
}

Rules summary

RuleDetails
When neededAny custom type in a pub fn signature on a #[component] impl
Struct fieldsMust be pub
Allowed field typesFelt, Word, Asset, AccountId, or other #[export_type] types
EnumsUnit variants supported
ModulesTypes in submodules work — just apply #[export_type] to each
OrderDeclaration order doesn't matter — forward references are resolved

Full API docs on docs.rs: miden (#[export_type] macro)