What is Smithy?
Smithy is an Interface Definition Language (IDL) created by AWS. You write your API contract once in.smithy files, and tools generate code for multiple languages from that single definition.
In this project, Smithy is the single source of truth for:
- Rust backend DTOs (request/response types)
- Shared enums used across the backend (
Gender,Currency,AccountStatus,MandateStatus, etc.) - TypeScript interfaces for the frontend
- Zod runtime validation schemas (optional)
The Files You’ll Work With
Smithy Models (you edit these)
Generated Code (never edit these manually)
How the Pipeline Works
The Big Picture
Step 1: You Write Smithy
A Smithy file defines what your API looks like — the operations, inputs, outputs, and errors:@rust* traits are codegen hints — they tell our custom code generator how to produce the Rust output. They don’t affect the Smithy model itself.
Step 2: just gen Runs the Pipeline
Internally, the codegen tool:
- Parses
model.json— classifies each shape as Structure, Enum, List, Map, or Skipped - Reads codegen traits —
@rustDerives,@rustSecret,@rustRename,@rustCrate, etc. - Groups by module — shapes go into
auth.rs,user.rs, etc. based on namespace - Topologically sorts — ensures a struct is defined before another struct references it
- Emits code — generates Rust structs/enums and TypeScript interfaces
Step 3: What Gets Generated
From this Smithy input:api_models/src/auth.rs):
sdk.ts):
@rustRenamechanged the struct name@rustSecretwrappedphone_numberinSecret<T>(Rust only — TS has no equivalent)- camelCase member names are lowered to snake_case automatically (these members are already snake_case)
- Optional fields (without
@required) getOption<T>in Rust and?:in TypeScript
Codegen Traits
Traits are annotations on Smithy shapes that control code generation. They’re defined incodegen-traits.smithy.
The Most Important Traits
Shared Enums: The @rustCrate Flow
Enums like Gender, Currency, AccountStatus, MandateStatus are used across many backend crates — not just api_models. They live in the common_enums crate.
The key: @rustCrate has dual behavior. When generating api_models, it acts like “import this from another crate”. When generating common_enums (via --common-enums-out), it generates the actual enum code.
The Codegen Tool Architecture
Key Source Files
Developer Workflow
Adding a New Field
Adding a New Shared Enum
Adding a New API Domain
- Create
smithy/model/new_domain.smithy - Define resource, operations, structures with codegen traits
- Register resource in
main.smithy - Run
just gen - New module appears in
api_models/src/new_domain.rs
Testing & CI
Two Layers of Protection
Snapshot tests catch bugs in the emitter code itself. They use fake test data and compare emitter output against saved.snap files. Your Smithy model changes don’t affect these tests — they only break if someone modifies the emitter functions.
gen-check catches forgotten regeneration. It runs the full pipeline and diffs the output against what’s committed. If you edited a Smithy file but forgot just gen, CI catches it.