Suprnova

A Laravel-inspired web framework for Rust.

License: MIT CHANGELOG

Suprnova - A Laravel-inspired web framework for Rust

Suprnova is a full-stack Rust web framework with Laravel 13’s developer experience and Tokio’s runtime model. Familiar API surfaces - Auth::login, Cache::remember, Mail::to, Event::dispatch, Eloquent-style models, #[handler], #[command], routes! - sit on top of a hyper / SeaORM / async-trait stack designed for long-lived connections, in-process workers, and concurrent IO. No request-per-process compromise.

Current main requires Rust 1.94.0 or newer. The tagged v2.1.0 release has the same Rust 1.94.0 floor.

cargo install --git https://github.com/eas4ai/suprnova.git --tag v2.1.0 suprnova-cli
suprnova new myapp --frontend svelte
cd myapp
suprnova serve

Your app is now serving at http://localhost:8765, with a Vite dev server proxied for the frontend.

Quick taste

If you’ve used Laravel, this should feel like home - only typed.

use std::time::Duration;
use suprnova::{handler, routes, attrs, inertia_response, json_response, Response};
use suprnova::{Auth, Cache, Event, RouteParam};
use crate::models::Post;
use crate::events::PostCreated;
use crate::requests::CreatePostRequest;

routes! {
    get!("/",             home),
    get!("/posts/{post}", show),
    post!("/posts",       store).middleware(Authenticate),
}

#[handler]
async fn home() -> Response {
    let popular = Cache::remember(
        "posts.popular",
        Some(Duration::from_secs(60)),
        || async { Post::query().db_where_op("views", ">", 1000).get().await },
    )
    .await?;
    Ok(inertia_response!("Home", { "posts": popular }))
}

#[handler]
async fn show(RouteParam(post): RouteParam<Post>) -> Response {
    Ok(json_response!({ "post": post }))
}

#[handler]
async fn store(req: CreatePostRequest) -> Response {
    let post = Post::create(attrs! {
        user_id: Auth::id().ok_or_else(|| FrameworkError::Unauthorized)?,
        title:   req.title,
        body:    req.body,
    })
    .await?;
    Event::dispatch(PostCreated { post: post.clone() }).await?;
    Ok(inertia_response!("Posts/Created", { "post": post }))
}

RouteParam<Post> applies the model’s global scopes and soft-delete filter automatically. Post::query() is the Eloquent builder (db_where_op is the Laravel-side alias of filter_op for arbitrary SQL operators). The #[handler] macro pulls FormRequests out of the body, route params out of the URI, and authenticated users out of the session - all type-checked.

What’s in the box

The Laravel-13 parity surface plus the Rust-native wins:

LayerWhat ships
HTTP & routingRouter, named routes, route groups & prefixes, parameter binding, resource routing, signed URLs, redirect helpers (Redirect::to / back / route / with_errors /…), #[handler] macro, 100% type-checked
MiddlewareCORS, CSRF, session, request-timeout, request-id, throttle / login-throttle, signed-URL verify, authenticated, email-verified, brute-force, custom global/group/per-route
Inertia 3 bridgeInertiaProps derive + TypeScript codegen, partial reloads, deferred / lazy props, version mismatch handling, SSR loopback, #[handler] integration, three starters: Svelte 5 / React 19 / Vue 3.5
Eloquent ORM#[suprnova::model] macro, 11 relation kinds (hasMany / belongsToMany / morph / polymorphic / through), eager loading, soft deletes, observers, global & local scopes, casts, 16 lifecycle events, factories + seeders, Collection<M>, 3 paginators, chunk/lazy/cursor iteration, multi-connection R/W split, transactions + savepoints + retry-on-deadlock
AuthAuth::user / login / once / check, named guards via AuthManager, remember-me, 2FA TOTP with recovery codes, email verification, password reset, brute-force lockout, login throttle, role/permission gates, #[policy] registration
DatabaseSeaORM-backed migrations + entity codegen, four databases: SQLite / Postgres / MySQL / MariaDB (MariaDB rides the MySQL driver and adds a native vector driver), DB::transaction with savepoints, query logging, multi-connection registry
CacheMemory, file, Redis - Cache::remember + lock-based Cache::lock + tags + atomic Redis Retry-After
Queues & jobsMemory, sync, Redis, database - queue routing (Queue::route, Job::queue, queue:work --queue=billing), middleware pipeline, batches, chains, retry schedules, failed-job store, unique jobs
Events & busEvent::dispatch, Listener / Subscriber, queued listeners, panic-isolated dispatcher, command/query bus
NotificationsMail / database / broadcast / Web Push channels, anonymous notifications, deferred dispatch
MailSMTP, Mailgun, Postmark, SendGrid, Resend, SES, log + in-memory transports, Markdown templates via Tera, fake() helper, queued mail
Broadcasting & WebSocketChannels (public / private / presence), BroadcastHub trait, sea-streamer fanout adapter, JSON-envelope protocol, supervised heartbeats with auto-restart
FilesystemLocal + S3 (R2 / B2 / MinIO compatible) via OpenDAL, path-traversal guard, atomic copy
VectorMemory, Qdrant, Pinecone, MariaDB native VECTOR(N) (HNSW + cosine/euclid/L1/L2) - first-class trait + drivers, no Postgres-only gatekeeping
PaymentsGeneric Payment / Subscription / CustomerStore / WebhookHandler traits + DB mirror; Stripe and Paddle reference adapters; webhook UNIQUE idempotency
ValidationRequired, Email, Min / Max / Between, RequiredIf / With / WithAll / Unless, Unique (async), Confirmed, custom rules via traits, validator derive integration
SchedulingSchedule::call / command / job, cron expressions, runInBackground, withoutOverlapping, supervised execution
WorkflowsDurable steps via #[workflow_step], #[workflow] orchestration, panic-recovery on the queue, exponential backoff with strict caps
ConsolePer-project console binary (the Rust analogue of php artisan), #[command] + #[derive(Command)] typed args, make:* generators, db:seed
ObservabilityStructured tracing everywhere, request IDs end-to-end, OpenTelemetry support, DB query logging via QueryExecuted events
Testing#[suprnova_test], in-memory SQLite via TestDatabase, fakes (Mail::fake(), Queue::fake(), Event::fake(), BroadcastHub recorder), expect! macro, handle_request in-process driver
Feature flagsDatabaseEvaluator + CachedEvaluator + admin CRUD + sub-second propagation via FeatureSync
Idempotency, rate-limit, CORS, CSRF, sessions, hashing, cryptoFirst-class; each subsystem ships fail-open vs fail-closed as an explicit policy choice

Starter kits

Don’t start from an empty scaffold (unless you want to o_O) - fork a kit:

  • Nebula - authentication (Breeze-tier): register, email verification, login with remember-me, password reset, and profile management, on Inertia 3 + Svelte 5.
  • Pulsar - a full product site and community on Vue 3.5 + Vuetify: everything in Nebula plus a marketing landing, dashboard, a Markdown docs pipeline, a blog with RSS, member profiles, taxonomy, role-based access control, and admin/moderation surfaces.
  • Directory starter - listings, moderation, and paid publication on Vue 3.5: owners submit listings, moderators review them, visitors search them, and publication is free or paid through Stripe and Paddle.

See Starter Kits for the full rundown, or run suprnova new for the plain scaffold on any of the three frontends.

End-to-end type safety

Define props in Rust once; use them in TypeScript with full autocomplete.

use suprnova::{handler, InertiaProps, inertia_response, Response};

#[derive(InertiaProps)]
pub struct HomeProps {
    pub title: String,
    pub user: UserDto,
}

#[derive(InertiaProps)]
pub struct UserDto {
    pub name: String,
    pub email: String,
}

#[handler]
pub async fn index() -> Response {
    Ok(inertia_response!("Home", HomeProps {
        title: "Welcome!".into(),
        user: UserDto {
            name: "Ada".into(),
            email: "[email protected]".into(),
        },
    }))
}

Run suprnova generate-types and your frontend/src/types/inertia-props.ts mirrors the Rust shape exactly. Change a field, regenerate, the compiler points at every component that needs to update.

Durable workflows

Workflow steps survive process restarts and retry with exponential backoff

  • jitter (strict cap, no doubling past it):
use suprnova::{workflow, workflow_step, start_workflow, FrameworkError};

#[workflow_step]
async fn fetch_user(user_id: i64) -> Result<String, FrameworkError> { ... }

#[workflow_step]
async fn send_welcome_email(user: String) -> Result<(), FrameworkError> { ... }

#[workflow]
async fn welcome_flow(user_id: i64) -> Result<(), FrameworkError> {
    let user = fetch_user(user_id).await?;
    send_welcome_email(user).await?;
    Ok(())
}

// Enqueue & run the worker:
let handle = start_workflow!(welcome_flow, 123).await?;
suprnova workflow:work

Documentation

  • Manual - 100+ chapters, every public subsystem. Pick a reading path: From Laravel (if you know Auth::user() / Eloquent / Blade) or From Rust Web (if you know Axum / Actix / Rocket).
  • Quickstart - small app end-to-end.
  • CHANGELOG.md - keep-a-changelog format.
  • Introduction - the design principles the framework is built on, including why every backend-bearing subsystem is a trait with drivers rather than one blessed implementation.
  • Contributing - the working agreement: full implementations only, well tested, production-ready. A feature ships when it’s done, not when it has a prototype.

Distribution model

Suprnova distributes via git, not crates.io. Generated apps depend on suprnova = { git = "https://github.com/eas4ai/suprnova.git", tag = "v2.1.0" }; the CLI installs via cargo install --git. Adapter crates (suprnova-payments-stripe, suprnova-payments-paddle, suprnova-web-push) follow the same model. The tag is the release: an app moves versions by editing one tag = line, each version’s CHANGELOG section is its release record, and as of v1.0.0 breaking changes land only behind a version bump that says so.

License

MIT, © 2026 Shawn McAllister & Dayem Siddiqui - see LICENSE. Suprnova began as a fork of Kit (MIT, © Dayem Siddiqui) and has since been taken in its own direction.


Summary

Laravel-inspired web framework for Rust (47 stars, early; eas4ai): ‘if you’ve used Laravel, this should feel like home — only typed’ — Eloquent-style ORM, migrations, controllers, artisan-style CLI tooling targeted.

Learnings

  • The rival named in the @gerardpg reply (‘much more complete ports’) to the loco.rs recommendation. Tiny and new vs loco’s 9.3k stars — the thread’s claim inverts the popularity gap, which is the tell to verify by hands-on use, not reply-chad authority. Interesting mainly as the Laravel-lineage branch (vs loco’s Rails lineage) of Rust batteries-included frameworks.

Gotchas

  • (none yet)

Hands-on

(research only)