Batteries-Included Rust MVC Framework

Convention.
Over configuration.
For Rust.

floz is a batteries-included MVC web framework for Rust. Built on ntex + floz ORM — get a production-ready server with auth, workers, database, and OpenAPI out of the box.

$ floz new my-app --template api
6 Modules
Feature-Gated
5 Macros
Zero Boilerplate
30+
Error Codes
3 Starters
Project Templates
🚀

App Builder

App::new().config().routes().run() — configure and launch in 5 lines.

🔒

Auth Module

JWT + API key generation + bcrypt hashing. Feature-gated, zero overhead if unused.

🗄️

ORM-First

floz ORM is a first-class citizen. Define schema once, query from handlers seamlessly.

Utility Macros

res!(), pp!(), echo!(), xquery!() — eliminate repetitive handler boilerplate.

🌐

CORS Middleware

Full CORS with builder pattern. Permissive for dev, restrictive for production.

💾

Smart Cache Layer

Declarative endpoint caching via #[route(cache(ttl = 60))] with automatic key-invalidation built natively inside the framework middleware pipeline.

📋

CLI Scaffolding

floz new, floz generate scaffold — generate projects and domain modules instantly.

Quick Start

Create a project, define a model, wire up handlers. From zero to running API in under a minute.

1. Create a Project

$ floz new my-app --template api
$ cd my-app && cp .env.example .env
$ cargo run

2. Zero-Boilerplate Endpoints

Attach the crud param to auto-generate REST endpoints seamlessly bridging your Postgres abstractions over to ntex.

use floz::prelude::*;

#[model("notes", crud(tag = "Notes"))]
pub struct Note {
    #[col(key, auto)]
    pub id: i32,
    pub title: Varchar,
    pub content: Text,
}

3. Or Define Custom Handlers

If you prefer standard control flows, you can inject the Db state natively and use the #[route] macros instead.

#[route(
    get: "/notes/custom",
    tag: "Notes",
    desc: "Fetch customized logic safely",
)]
async fn list_notes(db: web::types::State<Db>) -> HttpResponse {
    let notes = Note::all(&db).await.unwrap();
    res!(pp!(&notes).unwrap_or_default())
}

#[floz::main]
async fn main() -> std::io::Result<()> {
    App::new().run().await   // auto-wires traits into runtime boundaries
}

Why floz?

vs Loco.rs

floz advantages
  • Custom ORM with dirty tracking
  • PG LISTEN/NOTIFY bridge
  • API key + JWT + Cookie auth
  • Built-in OpenAPI + Swagger

vs Actix + SeaORM

floz advantages
  • Single framework — no assembly
  • CLI scaffolding tool
  • 30+ mapped error codes
  • Environment-driven config

vs Raw ntex

floz advantages
  • ORM-first with floz ORM
  • Auth module built-in
  • Utility macros (res!, pp!)
  • Project templates
FeatureflozLoco.rsActix+SeaORM
HTTP FrameworkntexAxumActix
ORMfloz ORMSeaORMSeaORM
Auth built-in✓ (JWT+API key)✓ (sessions)
CLI scaffolding
PG LISTEN/NOTIFY
OpenAPI built-in✓ (utoipa)
Background workers✓ (Redis)
Error code mapping30+ codesbasic