Rustlavel

Laravel's comfort,
Rust's guarantees.

As comfortable as Laravel while you write it. As calm as Rust when you deploy it.

crates.io docs.rs CI

Rustlavel takes what makes Laravel a pleasure to work in — conventions, an Artisan-style CLI, migrations, an Eloquent-shaped ORM, Blade-shaped templates, a debugging dashboard — and rebuilds it on Rust's terms.

It is not a translation. Where Laravel resolves things at runtime through reflection, Rustlavel resolves them at compile time, so a renamed column or a typo'd service is a build error rather than a null in production.

From scratch means from scratch

The HTTP server, the router, the JSON parser, the .env loader, the PostgreSQL and MySQL and TDS wire protocols, the template engine, the derive macros — all written here. The only dependencies are Tokio for the async runtime and a small set of cryptography crates.

The cryptography is the exception, deliberately. argon2, sha2, hmac, aes-gcm and rustls come from the RustCrypto and rustls projects. Hand-rolling a cipher, a KDF or a TLS stack is a vulnerability, not an achievement.

Getting started

cargo install rustlavel-cli

rustlavel new blog --with db,view,auth
cd blog
rustlavel serve

Or start from a working sign-in — two factors, roles and permissions, and an administration area, all written into your project where you can change them:

rustlavel new app --with auth-kit

Those files are yours, so they do not move when the framework does. A later release brings them forward by merging into what you wrote, never over it — and stops the build rather than guessing when you and the release changed the same thing:

rustlavel upgrade

Or add it to a project you already have:

cargo add rustlavel --features db,view

The guide walks through a first application, the cookbook answers the questions that come up afterwards, and the packages page lists what each feature flag turns on.

What a handler looks like

use rustlavel::prelude::*;

fn routes(r: &mut Router) {
    r.get("/users/{id}", |req: Request| async move {
        let db = req.state::<Database>().expect("the database");
        let id: i64 = req.param("id").and_then(|v| v.parse().ok()).unwrap_or(0);

        let user = db
            .select_one("select id, name from users where id = $1", &[Value::Int(id)])
            .await?
            .ok_or_else(|| Error::msg("no such user"))?;

        Ok::<_, Error>(Response::json(user.to_json()))
    });
}

Measured, not asserted

The repository carries a benchmark harness comparing Rustlavel against Axum, Loco.rs, Spring Boot and Laravel across eight endpoints, and the README publishes what it found — including where this framework loses. JSON serialisation is behind serde by about 1.5×, and the reason is structural rather than sloppy code.

The harness refuses to run on a busy machine, and refuses to measure an application until all eight of its endpoints answer 200 — because a 500 error page benchmarks as very fast, and that has already happened once here.