#orm #web-framework #laravel #framework

bin+lib torch-web

πŸ”₯ Fast, secure web framework for Rust with Laravel-inspired features, built-in ORM, CLI tools, and production-ready security

8 releases

0.2.8 Jul 20, 2025
0.2.7 Jul 16, 2025
0.1.0 Jul 10, 2025

#299 in HTTP server

Download history 4/week @ 2025-09-28 2/week @ 2025-10-05

449 downloads per month

MIT/Apache

745KB
14K SLoC

Torch πŸ”₯

The web framework that doesn't get in your way.

Torch is a fast, secure, and production-ready web framework for Rust. Built on Tokio and Hyper, it provides everything you need to build modern web applications with minimal configuration.

use torch_web::{App, Request, Response, main};

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let app = App::new()
        .get("/", |_req: Request| async {
            Response::ok().body("Hello, World! πŸ”₯")
        })
        .get("/users/:id", |req: Request| async move {
            let id = req.param("id").unwrap_or("Anonymous");
            Response::ok().body(format!("Hello, {}! πŸ”₯", id))
        });

    println!("πŸ”₯ Server running at http://localhost:3000");
    app.listen("127.0.0.1:3000").await
}

Buy Me A Coffee

Why developers choose Torch:

  • πŸš€ Blazing Fast - Built on Tokio + Hyper for maximum performance
  • ⚑ Compile-Time Routes - Zero-cost route validation with type-safe extractors
  • πŸ”₯ Ember Templates - Laravel Blade-inspired templating with inheritance
  • πŸ—οΈ Modular Architecture - Multi-crate project structure for large applications
  • πŸ›‘οΈ Secure by Design - Security features and beautiful error pages included
  • πŸ“Š Production Ready - Monitoring, caching, and database support
  • ⚑ Real-time Capable - WebSocket and SSE support out of the box
  • 🎯 Simple & Familiar - Sinatra-inspired API that just works
  • πŸ˜„ Fun Error Pages - Beautiful 404 pages with rotating flame-themed messages
  • πŸ› οΈ Powerful CLI - Laravel Artisan-inspired command-line tools for rapid development

✨ Features

⚑ Compile-Time Route Registration

  • Zero-cost abstractions - Routes validated at compile time
  • Type-safe parameter extraction - Path<T>, Query<T>, Json<T>
  • IDE support - Full autocomplete and error checking
  • No runtime overhead - All validation happens at build time
use torch_web::{routes, get, Path, Query};

routes! {
    #[get("/users/{id}")]
    async fn get_user(Path(id): Path<u32>) -> Response {
        Response::ok().json(format!("User {}", id))
    }

    #[get("/users")]
    async fn list_users(Query(params): Query<UserQuery>) -> Response {
        // Type-safe query parameter extraction
        Response::ok().json(params)
    }
}

πŸ”₯ Ember Template Engine

  • Laravel Blade-inspired syntax - @extends, @section, @foreach
  • Template inheritance for consistent layouts across pages
  • Component system with @include for reusable templates
  • Automatic XSS protection and input escaping
  • Hot reloading in development, intelligent caching in production
use torch_web::{ember::*, main};

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let app = App::new()
        .get("/", |_req| async {
            let data = EmberData::new()
                .with("title", "Welcome to Torch")
                .with("users", vec!["Alice", "Bob", "Charlie"]);

            ember("home", data).await
        });

    app.listen("127.0.0.1:3000").await
}

Template file (templates/home.ember):

@extends('layout')

@section('content')
    <h1>{{ $title }}</h1>

    @if(count($users) > 0)
        <ul>
        @foreach($users as $user)
            <li>πŸ”₯ {{ $user }}</li>
        @endforeach
        </ul>
    @else
        <p>No users found.</p>
    @endif
@endsection

πŸ—οΈ Modular Architecture

  • Multi-crate project structure - Prevent large monolithic crates
  • Workspace support - Organize code across focused crates
  • Clear separation of concerns - Core, Web, Auth, Database layers
  • Team scalability - Multiple teams can work in parallel
my-torch-app/
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ core/          # Business logic
β”‚   β”œβ”€β”€ web/           # Torch web application
β”‚   β”œβ”€β”€ auth/          # Authentication
β”‚   β”œβ”€β”€ database/      # Data layer
β”‚   └── api/           # External integrations

🎯 Type-Safe Extractors

  • Path parameters - Extract :id, :name with automatic type conversion
  • Query strings - Parse ?key=value into structs or HashMaps
  • JSON bodies - Deserialize request bodies with serde
  • Headers - Access any HTTP header with type safety
  • Application state - Share data across handlers with dependency injection
  • Multiple extractors - Combine any extractors in a single handler

πŸš€ High Performance

  • Built on Tokio + Hyper for maximum async performance
  • Handles thousands of concurrent connections efficiently
  • Zero-copy parsing and minimal allocations
  • HTTP/1.1 and HTTP/2 support

πŸ›‘οΈ Security First

  • Input validation and sanitization
  • HMAC request signing for API security
  • IP whitelisting and rate limiting
  • Security headers and CSRF protection

πŸ“Š Production Ready

  • Structured logging with tracing support
  • Metrics collection for monitoring
  • Health checks and graceful shutdown
  • Configuration management via TOML and environment variables

⚑ Real-time Support

  • WebSocket support for real-time applications
  • Server-Sent Events (SSE) for live updates
  • Connection management and broadcasting

πŸ—„οΈ Database & Caching

  • PostgreSQL support with connection pooling
  • Redis caching integration
  • Query builder for safe database operations
  • Migration runner for schema management

οΏ½ Beautiful Error Pages

  • Stunning default error pages with Torch branding
  • Sinatra-inspired 404 messages with flame themes
  • Fully customizable error page templates
  • Responsive design that works on all devices

πŸ”₯ Ember Template Engine

  • Laravel Blade-inspired syntax - familiar and powerful
  • Template inheritance with @extends and @section
  • Component system for reusable templates
  • Automatic XSS protection and input escaping
  • Hot reloading and intelligent caching
  • Zero-config setup - just create .ember files

πŸ”§ Developer Experience

  • Sinatra-inspired API - familiar and intuitive
  • Type-safe request/response handling
  • Middleware system for composable functionality
  • Hot reloading in development mode

πŸ› οΈ Developer Tools

# Install VS Code extension for .ember template support
code --install-extension enigmatikk.torch-ember

πŸš€ Quick Start

Installation

For full-featured applications with templates:

cargo add torch-web --features templates,json,database

For API-only applications:

cargo add torch-web --features json

For maximum features (production apps):

[dependencies]
torch-web = {
    version = "0.2.8",
    features = ["templates", "json", "database", "cache", "websocket"]
}

CLI Tool (Optional):

Install the Torch CLI for Laravel Artisan-like functionality:

cargo install torch-web --features cli

The CLI will automatically show PATH setup instructions for your operating system. If the torch command is not found after installation, follow the displayed instructions to add ~/.cargo/bin (or %USERPROFILE%\.cargo\bin on Windows) to your system PATH.

Quick CLI usage:

torch new my-app        # Create new Torch application
cd my-app
torch serve --hot       # Start development server with hot reload
torch make controller   # Generate controllers, models, etc.
torch --help           # Show all available commands

Available Features:

  • templates - Ember templating engine with Laravel Blade-like syntax
  • json - JSON request/response handling with serde
  • database - PostgreSQL support with SQLx
  • cache - Redis caching integration
  • websocket - WebSocket support for real-time apps
  • api - Enhanced API development tools
  • cli - Command-line interface with Laravel Artisan-like functionality
  • cli - Laravel Artisan-inspired command-line tools

πŸ› οΈ Torch CLI - Laravel Artisan for Rust

Torch includes a powerful CLI tool inspired by Laravel's Artisan, providing rapid scaffolding and development utilities:

# Install the CLI
cargo install torch-web --features cli

# Create a new Torch application
torch new my-app

# Generate controllers, models, and more
torch make controller UserController --resource
torch make model User --migration --factory --seeder

# Start development server with hot reload
torch serve --hot

# Run database migrations
torch migrate

# Interactive REPL for debugging
torch tinker

# Build for production
torch build --release

Available CLI Commands

Project Management:

  • torch new <name> - Create new Torch application
  • torch serve --hot - Development server with hot reload
  • torch build --release - Production build with optimizations

Code Generation:

  • torch make controller <name> - Generate controllers (with --resource, --api flags)
  • torch make model <name> - Generate models (with --migration, --factory, --seeder flags)
  • torch make middleware <name> - Generate middleware
  • torch make template <name> - Generate Ember templates
  • torch make migration <name> - Generate database migrations
  • torch make test <name> - Generate tests

Database Operations:

  • torch migrate - Run migrations (with rollback, fresh, status subcommands)
  • torch db seed - Seed database
  • torch db status - Show database status

Development Tools:

  • torch tinker - Interactive REPL shell
  • torch route list - Show all routes
  • torch cache clear - Clear application caches
  • torch optimize - Optimize for production

See the CLI Documentation for complete command reference and CLI Tutorial for a step-by-step guide.

Hello World

use torch_web::{App, Request, Response, main};

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let app = App::new()
        .get("/", |_req: Request| async {
            Response::ok().body("Hello, World! πŸ”₯")
        })
        .get("/hello/:name", |req: Request| async move {
            let name = req.param("name").unwrap_or("Anonymous");
            Response::ok().body(format!("Hello, {}! πŸ”₯", name))
        })
        .get("/json", |_req: Request| async {
            #[cfg(feature = "json")]
            {
                use serde_json::json;
                Response::ok()
                    .json(&json!({
                        "message": "Hello from Torch!",
                        "framework": "torch",
                        "version": "0.1.0"
                    }))
                    .unwrap()
            }
            #[cfg(not(feature = "json"))]
            {
                Response::ok()
                    .content_type("application/json")
                    .body(r#"{"message": "Hello from Torch!", "framework": "torch"}"#)
            }
        });

    println!("πŸ”₯ Starting Torch Hello World example...");
    app.listen("127.0.0.1:3000").await
}

Try the Example

# Clone the repository
git clone https://github.com/Enigmatikk/torch.git
cd torch

# Run the hello world example
cargo run --example hello_world

# Visit http://localhost:3000 to see it in action!

πŸ”₯ Ember Template Engine

Torch includes Ember, a powerful templating engine inspired by Laravel's Blade but built for Rust performance:

use torch_web::{App, ember::*, main};

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let app = App::new()
        .get("/", |_req| async {
            let data = EmberData::new()
                .with("title", "Welcome to Torch")
                .with("users", vec!["Alice", "Bob", "Charlie"]);

            ember("home", data).await
        });

    app.listen("127.0.0.1:3000").await
}

Template Syntax

Create templates/home.ember:

@extends('layout')

@section('content')
    <h1>{{ $title }}</h1>

    @if(count($users) > 0)
        <ul>
        @foreach($users as $user)
            <li>πŸ”₯ {{ $user }}</li>
        @endforeach
        </ul>
    @else
        <p>No users found.</p>
    @endif
@endsection

Create templates/layout.ember:

<!DOCTYPE html>
<html>
<head>
    <title>{{ $title }} - My App</title>
</head>
<body>
    <div class="container">
        @section('content')
            <p>Default content</p>
        @endsection
    </div>
</body>
</html>

Ember Features

  • 🎨 Familiar Syntax: Laravel Blade-inspired directives
  • πŸ—οΈ Template Inheritance: @extends, @section, @endsection
  • πŸ”„ Loops & Conditionals: @foreach, @if, @else, @endif
  • πŸ“¦ Components: @include('partial') for reusable templates
  • πŸ”’ Auto-Escaping: XSS protection built-in
  • ⚑ Performance: Compiled templates with intelligent caching
  • πŸ”₯ Hot Reload: Templates update automatically in development

πŸš€ Real-World Example: Multi-Step Registration Wizard

Here's a comprehensive example showing how Torch's features work together in a production-ready application:

use torch_web::{App, Request, Response, main, ember::*};
use std::collections::HashMap;
use serde::{Deserialize, Serialize};

// Step 1: Basic Information
#[derive(Debug, Deserialize, Serialize, Clone)]
struct BasicInfo {
    first_name: String,
    last_name: String,
    email: String,
    phone: String,
}

// Registration wizard state
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
struct RegistrationData {
    basic_info: Option<BasicInfo>,
    current_step: u8,
}

// Session store (use Redis in production)
type SessionStore = std::sync::Arc<std::sync::Mutex<HashMap<String, RegistrationData>>>;

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let sessions: SessionStore = std::sync::Arc::new(std::sync::Mutex::new(HashMap::new()));
    let sessions_clone = sessions.clone();

    let app = App::new()
        // Home page with beautiful template
        .get::<_, ()>("/", |_req: Request| async {
            let data = EmberData::new()
                .with("title", "Welcome to Torch")
                .with("page_title", "Multi-Step Registration Wizard")
                .with("description", "Experience the power of Torch with Ember templating");

            ember("home", data).await
        })

        // Registration wizard - Step 1
        .get::<_, ()>("/register", move |req: Request| {
            let sessions = sessions_clone.clone();
            async move {
                let session_id = get_or_create_session(&req);
                let registration_data = get_session_data(&sessions, &session_id);

                let data = EmberData::new()
                    .with("title", "Registration - Step 1")
                    .with("step", 1)
                    .with("step_title", "Basic Information")
                    .with("progress", 33)
                    .with("first_name", registration_data.basic_info
                        .as_ref().map(|b| b.first_name.clone()).unwrap_or_default());

                ember("registration/step1", data).await
            }
        })

        // Handle form submission with session state
        .post::<_, ()>("/register/step1", move |req: Request| {
            let sessions = sessions.clone();
            async move {
                let session_id = get_or_create_session(&req);

                // Parse form data (simplified for example)
                let basic_info = BasicInfo {
                    first_name: "John".to_string(),
                    last_name: "Doe".to_string(),
                    email: "john.doe@example.com".to_string(),
                    phone: "+1-555-0123".to_string(),
                };

                // Update session state
                update_session_data(&sessions, &session_id, |data| {
                    data.basic_info = Some(basic_info);
                    data.current_step = 2;
                });

                // Redirect to next step
                Response::redirect_found("/register/step2")
            }
        });

    println!("πŸ”₯ Torch Registration Wizard starting...");
    println!("🌐 Visit http://localhost:3000 to see the demo");

    app.listen("127.0.0.1:3000").await
}

// Helper functions for session management
fn get_or_create_session(req: &Request) -> String {
    req.header("x-session-id").unwrap_or("demo-session").to_string()
}

fn get_session_data(sessions: &SessionStore, session_id: &str) -> RegistrationData {
    let sessions = sessions.lock().unwrap();
    sessions.get(session_id).cloned().unwrap_or_default()
}

fn update_session_data<F>(sessions: &SessionStore, session_id: &str, updater: F)
where F: FnOnce(&mut RegistrationData)
{
    let mut sessions = sessions.lock().unwrap();
    let mut data = sessions.get(session_id).cloned().unwrap_or_default();
    updater(&mut data);
    sessions.insert(session_id.to_string(), data);
}

Template Structure:

templates/
β”œβ”€β”€ layouts/
β”‚   └── main.ember          # Base layout with CSS, header, footer
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ header.ember        # Navigation component
β”‚   β”œβ”€β”€ footer.ember        # Footer component
β”‚   └── progress_bar.ember  # Reusable progress indicator
└── registration/
    β”œβ”€β”€ step1.ember         # Extends main layout
    β”œβ”€β”€ step2.ember         # Extends main layout
    └── step3.ember         # Extends main layout

Layout Template (templates/layouts/main.ember):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ $title }} - Torch Demo</title>
    <style>
        body { font-family: 'Segoe UI', sans-serif; margin: 0; }
        .container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
        /* Beautiful responsive CSS... */
    </style>
</head>
<body>
    @include('components/header')

    <main class="container">
        @section('content')
            <p>Default content</p>
        @endsection
    </main>

    @include('components/footer')
</body>
</html>

Step Template (templates/registration/step1.ember):

@extends('layouts/main')

@section('content')
    @include('components/progress_bar')

    <div class="form-container">
        <h2>{{ $step_title }}</h2>

        <form method="POST" action="/register/step1">
            <div class="form-group">
                <label>First Name</label>
                <input type="text" name="first_name" value="{{ $first_name }}" required>
            </div>

            <div class="form-group">
                <label>Last Name</label>
                <input type="text" name="last_name" value="{{ $last_name }}" required>
            </div>

            <button type="submit">Continue to Step 2 β†’</button>
        </form>
    </div>
@endsection

This example demonstrates:

  • πŸ”₯ Template inheritance for consistent layouts
  • πŸ“¦ Component reuse with @include directives
  • πŸ”„ Session state management across multiple steps
  • πŸ“ Form handling with validation and redirects
  • 🎨 Beautiful responsive design with consistent theming
  • πŸ—οΈ Modular structure ready for team development

🎯 Type-Safe Extractors

Torch features a powerful extractors system that makes handling requests type-safe and ergonomic:

use torch_web::{App, main, extractors::*};
use std::collections::HashMap;

#[derive(Clone)]
struct AppState {
    counter: std::sync::Arc<tokio::sync::Mutex<u64>>,
}

#[main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let state = AppState {
        counter: std::sync::Arc::new(tokio::sync::Mutex::new(0)),
    };

    let app = App::new()
        .with_state(state)

        // Path parameters
        .get("/users/:id", |Path(user_id): Path<u32>| async move {
            format!("User ID: {}", user_id)
        })

        // Query parameters
        .get("/search", |Query(params): Query<HashMap<String, String>>| async move {
            let query = params.get("q").unwrap_or(&"*".to_string());
            format!("Searching for: {}", query)
        })

        // JSON body (with json feature)
        .post("/users", |Json(user): Json<serde_json::Value>| async move {
            format!("Creating user: {}", user)
        })

        // Headers
        .get("/info", |Headers(headers): Headers| async move {
            let user_agent = headers.get("user-agent")
                .and_then(|v| v.to_str().ok())
                .unwrap_or("Unknown");
            format!("Your browser: {}", user_agent)
        })

        // Application state
        .post("/increment", |State(state): State<AppState>| async move {
            let mut counter = state.counter.lock().await;
            *counter += 1;
            format!("Counter: {}", *counter)
        })

        // Multiple extractors
        .get("/api/:version/search", |
            Path(version): Path<String>,
            Query(params): Query<HashMap<String, String>>,
            State(state): State<AppState>,
        | async move {
            let counter = state.counter.lock().await;
            let query = params.get("q").unwrap_or(&"*".to_string());
            format!("API v{}: Searching '{}' (requests: {})", version, query, *counter)
        });

    app.listen("127.0.0.1:3000").await
}

Available Extractors

  • Path<T> - Extract path parameters (:id, :name, etc.)
  • Query<T> - Extract query string parameters (?key=value)
  • Json<T> - Extract and deserialize JSON request bodies
  • Headers - Access request headers
  • State<T> - Access shared application state
  • Multiple extractors - Combine any extractors in a single handler

🎨 Beautiful Error Pages

One of Torch's standout features is its beautiful, Sinatra-inspired error pages:

Fun 404 Messages

Torch includes rotating 404 messages with flame themes:

  • "πŸ”₯ Torch doesn't know this ditty, but it's got plenty of other hot tracks!"
  • "πŸ”₯ This path hasn't been lit by the Torch yet."
  • "πŸ”₯ Even the brightest flame can't illuminate this missing page."

Stunning Design

  • Modern dark theme with professional gradients
  • Torch branding with beautiful SVG flame logo
  • Fully responsive - works on desktop, tablet, and mobile
  • Smooth animations and hover effects

Customizable

use torch_web::ErrorPages;

let custom_pages = ErrorPages::new()
    .custom_404("Your custom 404 HTML here")
    .custom_500("Your custom 500 HTML here");

let app = App::new()
    .error_pages(custom_pages);

πŸ”§ Feature Flags

Torch uses feature flags to keep your binary size small:

  • default - Includes JSON support
  • json - JSON serialization with serde
  • production - All production features (monitoring, security, etc.)
  • security - Security middleware and utilities
  • websocket - WebSocket and real-time features
  • database - PostgreSQL support with connection pooling
  • cache - Redis caching integration
  • api - API documentation generation
  • config - TOML configuration support
  • monitoring - Metrics and structured logging

πŸ—οΈ Architecture

Torch is built on proven Rust technologies:

  • Tokio - Async runtime for high performance
  • Hyper - Fast HTTP implementation
  • Tower - Middleware and service abstractions
  • Serde - Serialization framework
  • Tracing - Structured logging and diagnostics

πŸ”§ Configuration

Torch supports configuration through TOML files and environment variables.

Configuration File

Create a torch.toml file in your project root:

[server]
host = "0.0.0.0"
port = 8080
max_connections = 10000
request_timeout_secs = 30

[security]
enable_cors = true
enable_security_headers = true
enable_rate_limiting = true
per_ip_rps_limit = 100

[monitoring]
enable_metrics = true
enable_request_logging = true
log_level = "info"

[database]
url = "postgresql://user:pass@localhost/db"
max_connections = 10

[cache]
redis_url = "redis://localhost:6379"
default_ttl_secs = 3600

Environment Variables

export TORCH_HOST=0.0.0.0
export TORCH_PORT=8080
export TORCH_DATABASE_URL=postgresql://user:pass@localhost/db
export TORCH_REDIS_URL=redis://localhost:6379

πŸ›‘οΈ Security Features

use torch_web::security::*;

// Input validation and sanitization
let app = App::new()
    .middleware(InputValidator::new())
    .middleware(SecurityHeaders::new())
    .middleware(RateLimiter::new(100)); // 100 requests per second

// HMAC request signing
let signing = RequestSigning::new("your-secret-key");
let app = app.middleware(signing);

// IP whitelisting
let whitelist = IpWhitelist::new()
    .allow_ip("192.168.1.1")
    .allow_range("10.0.0.0/8");
let app = app.middleware(whitelist);

πŸ“Š Production Features

use torch_web::production::*;

// Metrics and monitoring
let app = App::new()
    .middleware(MetricsCollector::new())
    .middleware(PerformanceMonitor::new())
    .middleware(RequestLogger::new());

// Health check endpoint
let app = app.get("/health", |_req| async {
    Response::ok().json(&serde_json::json!({
        "status": "healthy",
        "uptime": "24h",
        "version": "0.1.0"
    })).unwrap()
});

⚑ Advanced Features

πŸ—οΈ Modular Project Structure

Torch supports organizing large applications across multiple crates to prevent any single crate from becoming too large:

# Workspace Cargo.toml
[workspace]
members = [
    "crates/core",      # Business logic
    "crates/web",       # Torch web application
    "crates/auth",      # Authentication
    "crates/database",  # Data layer
    "crates/api",       # External integrations
]

[workspace.dependencies]
torch-web = { version = "0.2.8", features = ["templates", "json"] }

Benefits:

  • βœ… Faster builds - Only changed crates are recompiled
  • βœ… Parallel compilation - Crates can be compiled in parallel
  • βœ… Clear dependencies - Dependency graph is explicit
  • βœ… Team scalability - Multiple teams can work simultaneously
  • βœ… Code reuse - Share components across different applications

⚑ Compile-Time Route Validation

Leverage Rust's fantastic compiler for zero-cost route registration:

use torch_web::{routes, get, post, Path, Query, Json};

// Compile-time validated routes with type-safe extractors
routes! {
    #[get("/users/{id}")]
    async fn get_user(Path(id): Path<u32>) -> Response {
        // id is guaranteed to be a valid u32 at compile time
        Response::ok().json(format!("User {}", id))
    }

    #[get("/users")]
    async fn list_users(Query(params): Query<UserQuery>) -> Response {
        // params is type-checked at compile time
        Response::ok().json(params)
    }

    #[post("/users")]
    async fn create_user(Json(user): Json<CreateUserRequest>) -> Response {
        // JSON deserialization is validated at compile time
        Response::created().json("User created")
    }
}

Compile-Time Benefits:

  • βœ… Zero runtime overhead - All validation happens at build time
  • βœ… Type safety - Parameters are type-checked by the compiler
  • βœ… IDE support - Full autocomplete and error checking
  • βœ… Early error detection - Catch route issues before deployment

🎨 Consistent Theming System

Build applications with consistent headers, footers, and menus across multiple pages:

// Shared layout with navigation
// templates/layouts/app.ember
```html
<!DOCTYPE html>
<html>
<head>
    <title>{{ $title }} - My App</title>
    <link rel="stylesheet" href="/css/app.css">
</head>
<body>
    @include('components/header')
    @include('components/navigation')

    <main class="content">
        @section('content')
            <p>Default content</p>
        @endsection
    </main>

    @include('components/footer')
</body>
</html>
// All pages inherit the same layout
// templates/users/index.ember
```html
@extends('layouts/app')

@section('content')
    <h1>{{ $page_title }}</h1>
    @foreach($users as $user)
        <div class="user-card">{{ $user.name }}</div>
    @endforeach
@endsection

Theming Benefits:

  • βœ… Consistent design - Shared layouts ensure visual consistency
  • βœ… Component reuse - Headers, footers, menus defined once
  • βœ… Easy maintenance - Update navigation in one place
  • βœ… Responsive design - CSS and JavaScript shared across pages

πŸ”„ Middleware System

Torch provides a powerful and flexible middleware system:

use torch_web::middleware::*;

// Built-in middleware
let app = App::new()
    .middleware(Logger::new())
    .middleware(Cors::permissive())
    .middleware(SecurityHeaders::new())
    .middleware(Compression::new());

// Custom middleware
let app = app.middleware(|req: Request, next| {
    Box::pin(async move {
        let start = std::time::Instant::now();
        let response = next(req).await;
        let duration = start.elapsed();
        println!("Request took: {:?}", duration);
        response
    })
});

🎯 Use Cases

Web APIs

  • REST APIs with JSON serialization
  • GraphQL endpoints
  • Microservices architecture
  • Real-time applications with WebSockets

Production Applications

  • High-traffic websites with caching
  • Enterprise applications with security
  • Data processing pipelines
  • Integration services with monitoring

πŸ“ˆ Performance

Torch is built for speed and efficiency:

Why Torch is fast:

  • Zero-copy parsing - Minimal allocations in hot paths
  • Async all the way down - Built on Tokio's proven runtime
  • Smart defaults - Optimized configurations out of the box
  • Efficient routing - Fast path matching with minimal overhead

Benchmark it yourself:

# Clone the repository
git clone https://github.com/Enigmatikk/torch.git
cd torch

# Run the hello world example
cargo run --example hello_world --release

# Test with your favorite load testing tool
wrk -t12 -c400 -d30s http://localhost:3000/

πŸ§ͺ Try It Now

# Clone and run in 30 seconds
git clone https://github.com/Enigmatikk/torch.git
cd torch

# Run the hello world example
cargo run --example hello_world

# Visit http://localhost:3000 to see:
# - Hello World endpoint
# - Path parameters (/hello/:name)
# - JSON responses (/json)
# - Beautiful 404 pages (try /nonexistent)

πŸš€ Requirements

  • Rust 1.75+ (uses latest async features)
  • Tokio runtime (included with Torch)

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/Enigmatikk/torch.git
cd torch

# Run tests
cargo test --all-features

# Run examples
cargo run --example hello_world                    # Basic routing
cargo run --example registration_wizard --features templates,json  # Multi-step wizard
cargo run --example ember_demo --features templates               # Template showcase
cargo run --example enhanced_extractors            # Type-safe extractors

# Check formatting
cargo fmt --check

# Run clippy
cargo clippy --all-features

πŸ“„ License

This project is licensed under the MIT OR Apache-2.0 license.

πŸ™ Acknowledgments

  • Sinatra - Inspired our simple, intuitive API design
  • Axum - Architectural inspiration for middleware
  • Rust Community - For building an amazing ecosystem

πŸš€ What's Next?

  1. ⭐ Star this repo if Torch looks useful to you
  2. πŸ§ͺ Try the registration wizard - cargo run --example registration_wizard --features templates,json
  3. πŸ”₯ Explore Ember templates - See how template inheritance and components work
  4. πŸ—οΈ Build a modular app - Use the multi-crate structure for large projects
  5. ⚑ Leverage compile-time routes - Get type safety and zero-cost abstractions
  6. 🀝 Contribute - we'd love your help making Torch even better

Join the Community


Built with ❀️ and πŸ”₯ for developers who ship fast

Torch - The web framework that doesn't get in your way πŸ”₯

Dependencies

~5–27MB
~345K SLoC