A multi-crate Rust practice of
Clean & Hexagonal Domain Driven Design, combined Dioxus's fullstack.
First, look at the high-level crate split:
crates/
- adapters/ # Clean Core
- app/ # Clean Core
- domain/ # Clean Core
- infra/ # Clean Core
- ui/ # User Interface
- worker/ # User InterfaceThis architecture is inspired by axum-clean-architecture by @Thodin, and adapted to Dioxus fullstack engineering practices.
Core dependency direction:
domain <- app(application) <- adapter <- infra(infrastructure) <- user interface
crates/domain/src
├── auth
├── error.rs
├── lib.rs
├── project
├── repo
└── snapshotauth / project / repo / snapshot: domain models split by business subdomainerror.rs: domain-level error semanticslib.rs: domain module export boundary
The Domain layer carries domain semantics and invariants. It focuses on modeling, not orchestration or infrastructure details.
crates/domain/src/project
├── entity.rs (Entity)
├── event.rs (Domain Event)
├── mod.rs
└── value_object.rs (Value Object)crates/app/src
├── app_error.rs
├── auth
├── backup
├── common
├── lib.rs
├── prelude.rs
├── project
├── repo
└── snapshotcommon,app_error.rs: cross-use-case shared business logic and unified error semanticsauth / backup / project / repo / snapshot: use-case modules by domain areaprelude.rs: common exports for the application layer
The Application layer handles use-case orchestration. It depends on external capabilities through ports, not concrete infrastructure implementations.
crates/app/src/project
├── command.rs (CQRS - command use cases)
├── event_handler.rs (domain-event-driven orchestration)
├── impls (Rich Domain Model-oriented implementations)
├── mod.rs
├── port.rs (Hexagonal Port)
└── query.rs (CQRS - query use cases)crates/adapters/src
├── auth
├── clock.rs
├── github.rs
├── lib.rs
├── persistence
└── prelude.rspersistence: storage adapter implementationsauth: authentication/authorization-related adaptersgithub.rs: external API adapterclock.rs: time capability adapter
The Adapter layer performs technical orchestration and boundary translation, implementing Application ports with concrete technologies.
Note: HTTP endpoint implementation code is in crates/ui/src/IO. This is intentional: physical location in ui, architectural ownership in Adapter.
crates/adapters/src/persistence/psql
├── backup.rs (data backup implementation)
├── db.rs (database connection implementation)
├── mod.rs
├── project_repo.rs (Project repository implementation)
├── repo_repo.rs (Repo repository implementation)
├── repo_tag_repo.rs (Tag repository implementation)
├── runtime.rs (runtime composition)
└── snapshot_repo.rs (Snapshot repository implementation)crates/infra/src
├── config
├── lib.rs
└── setup.rsconfig: configuration model and sourcessetup.rs: composition entry, initialization, and dependency injectionlib.rs: infrastructure module exports
The Infrastructure layer handles system composition and startup only. It does not carry business rules.
crates/infra/src/config
├── mod.rs (configuration module exports)
├── settings.rs (configuration structure definitions)
└── toml (environment config directory)UI and Worker both belong to User Interface, but they serve different interaction targets:
UI: human-facing interactionWorker: scheduler/background execution
crates/ui/src
├── IO
├── components
├── impls
├── js
├── lib.rs
├── main.rs
├── root
└── typesmain.rs: UI/Web entry and fullstack server startup entryroot: page layout and router structurecomponents: reusable UI components- For KISS reasons, page-level components are also placed here for now, influenced by Next.js App Router-style organization
types: front-end view model data structuresimpls / js: front-end implementation details
Notice: although IO is physically under ui, its HTTP endpoint logic is an Axum adapter and belongs to the Adapter layer architecturally.
See also:
Dioxus v0.7.0+ provides convenient macros such as #[post] and #[get]. They provide a seamless fullstack development experience while keeping code organization clean. For details, see Dioxus official docs.
For cleaner SSR handling in complex components, this project uses a mod-like component blueprint:
crates/ui/src/components/**/exampleComp/
├── mod.rs # component
├── skeleton.rs # loading fallback
├── error.rs # error fallback
├── hook.rs # private hook
├── context.rs # private context
├── style.css # optional, when Tailwind is not convenient
├── (optional)sub-Comp/ # optional nested component blueprintThe IOCell component is used to centralize SSR handling logic.
A minimal pure-component template (compName.rs) is also supported but it desn't need a word.
crates/worker/src
└── main.rsA lightweight application entry that reuses core capabilities. Currently it is used for a snapshot-related background task.
All diagrams are drawn in Excalidraw.

