IET Framework

A Rust framework for building web and backend applications as one deployable program — out of modules you can reuse in the next application.

You write ordinary Rust and Cargo crates. The framework supplies the production plumbing — HTTP serving, validation, configuration, persistence, authentication, background workers — and a module pattern (contract, implementation, adapter) that keeps business rules independent of the database, user interface, and caller that happen to use them.

There is no runtime container and no service locator; the wiring lives in your composition root, where the compiler checks it.

Start the 5-minute quickstart → · Run the complete browser starter → · Read the framework architecture →

See it run

The smallest useful application is one file. This serves HTTP and shuts down cleanly on Ctrl+C:

examples/my-first-app/src/main.rsrust
use axum::routing::get;
use iet_http_axum::{HostConfig, HttpHost, RestApi};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let router = RestApi::new()
        .route("/hello", get(hello))
        .finish(());

    let config = HostConfig {
        address: "127.0.0.1:3012".parse()?,
        ..HostConfig::default()
    };

    let host = HttpHost::bind(config, router).await?;
    println!("Open http://127.0.0.1:3012/hello");

    host.run(async {
        let _ = tokio::signal::ctrl_c().await;
    })
    .await?;

    Ok(())
}

async fn hello() -> &'static str {
    "Hello from my application"
}
sh
# Terminal 1
cargo run --manifest-path examples/my-first-app/Cargo.toml

# Terminal 2
curl http://127.0.0.1:3012/hello
# Hello from my application

Two framework types do the plumbing: RestApi builds an Axum router with HTTP conventions, and HttpHost owns the listener and graceful shutdown. Everything else is your Rust.

Follow the quickstart: create the project, run it, change it →

What the framework gives you

I want to buildCratesWhat you get
A JSON APIiet-http-axumRouter conventions, typed extractors, ValidatedJson, consistent problem responses
Server-rendered pagesiet-http-htmx-axum, iet-uiEscaped HTML components and forms; HTMX enhances but is not required
Validation and errorsiet-coreOne Validate trait and one AppError type, honored across layers
Persistent storageiet-db, iet-db-timescale, iet-storagePool lifecycle, reviewed migrations, SQLx/TimescaleDB adapter, object streams
Sign-in and sessionsiet-auth, iet-auth-basic, session crates, integrationsPasswords, sessions (cache, database, or JWT), CSRF, revocations
Roles and resource accessiet-authz, iet-auth-rbac, iet-auth-aclDeny-by-default policy ports with separately selected storage
Configurationiet-config, iet-config-envTyped, immutable settings read once at startup
Background workiet-app, iet-runtime-tokioWorkers with prepare/start phases and a bounded shutdown drain
Caching and rate limitingiet-cache-memory, iet-rate-limitTyped cache and admission contracts with backend-selected scope
Telemetryiet-telemetry, iet-telemetry-otelBounded operation names and OpenTelemetry wire-up

The capability guides and reference pages cover the rows above in detail. Prefer a preset? iet-stack-web-axum and iet-stack-auth-htmx-axum compose these pieces for you.

See it all working together

The checked-in browser starter combines sign-in, projects, tasks, search, pagination, and a database into one server-rendered app — no single-page framework:

<img src={require('@site/static/img/starter/workspace.webp').default} alt="The starter workspace with a project and its tasks" />

Run it locally in a few Docker commands: Explore the browser application →

Reuse is the point

A module is one capability with three parts: a contract that says what it does, an implementation that says how, and an adapter that connects it to one caller. Because the contract depends on nothing outward, the same module runs in a web API and a command-line app unchanged — here is the checked-in examples/reusable-notes proof:

Command-line application (apps/report)sh
$ cargo run --manifest-path examples/reusable-notes/Cargo.toml -p notes-report
note 1: Prepared from a command-line job
Web application (apps/api)sh
$ curl -s -X POST http://127.0.0.1:3014/notes -d '{"text":"same module, web caller"}'
{"id":1,"text":"same module, web caller"}
One application · one process
notesprojectstasks
Modules call each other in-process through contracts.
Another application · same module
web APIcommand-line app
notesthe same crate, reused
No copying of the rules — add the crate, compose it.

You do not need a module split on day one. Start with one crate and promote a capability into a reusable module when a second application actually needs it. How modules fit together →

What makes this different

01

Ordinary Rust

No custom DSL and no generated server. If you know Rust and Axum, you already know most of the code you will write.

02

Reusable by construction

Contracts point at nothing outward, so the database, the UI, or the caller can be replaced without rewriting the rules between them.

03

One process, no hidden wiring

A modular monolith: modules call in-process, concrete types are fixed at compile time, and nothing is looked up by name on the request path.

Performance is a property of the whole application

The framework keeps dynamic dispatch out of its core ports, but it cannot make a slow query or a deployment fast. Measure your application under its real workload before claiming a performance result.

Where to go next

Run your first app Quickstart

One endpoint on screen in about five minutes, with every command shown.

See a complete application Run the browser starter

Sign-in, pages, forms, and persistence, already wired from framework modules.

Build step by step Tutorial: a validated JSON API

From the quickstart to validated input, stored notes, and tests.

Understand the design How the framework is built

Core, features, integrations, and stacks — with the full crate catalog.

Current scope

Examples use local path dependencies from this checkout. No published release or application generator is assumed. The framework is evolving; examples are learning applications, not production-ready deployments.

IET Framework documentation — built with the IET Framework.