<p align="center">
<h1 align="center">๐ Velto</h1>
<p align="center">
<em>A minimal async web framework for Rust, built for clarity, speed, and joy.</em>
</p>
<p align="center">
<a href="https://crates.io/crates/velto">
<img src="https://img.shields.io/crates/v/velto?style=flat-square" alt="Crates.io">
</a>
<a href="https://github.com/Pjdur/velto/actions">
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pjdur/velto/.github%2Fworkflows%2Frust.yml?style=flat-square">
</a>
<a href="https://docs.rs/velto">
<img src="https://img.shields.io/docsrs/velto?style=flat-square" alt="Docs.rs">
</a>
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License: MIT">
</a>
</p>
</p>
---
## โจ Features
- ๐งญ Intuitive routing with `route!(...)` and `route_any!(...)` macros
- ๐งต Templating with `render!`, `{% include %}`, and `{% extends %}` support
- โก Fully async, powered by [`async_tiny`](https://crates.io/crates/async_tiny)
- ๐ LiveReload support in development mode
- ๐ Static file serving with zero config
- ๐ Global middleware support via `App::use_middleware()`
- ๐ง Minimal boilerplate via `velto::prelude`
- ๐งช Built-in testing with `TestRequest`
- ๐ First-class CLI support via [`velto-cli`](https://crates.io/crates/velto-cli)
---
## ๐ฆ Installation
Add Velto to your `Cargo.toml`:
```toml
[dependencies]
velto = "1.9.0"
```
Or use [`velto-cli`](https://crates.io/crates/velto-cli) to scaffold a new project instantly:
```bash
cargo install velto-cli
velto new my-app
cd my-app
velto run
```
---
## ๐ Quick Start
```rust
use velto::prelude::*;
use velto::middleware::logger; // Built-in middleware
fn homepage(_req: &Request) -> Response {
render!("index.html", {
"title" => "Welcome to Velto",
"message" => "Fast. Clean. Rusty."
})
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
app.use_middleware(logger); // Add middleware
app.enable_dev_mode(); // Enables LiveReload
route!(app, "/" => homepage);
app.serve_static("static");
app.run("127.0.0.1:8080").await
}
```
---
## ๐ Middleware
Velto supports global middleware functions that run before and/or after route handlers.
Use `App::use_middleware()` to register middleware like logging, authentication, or header injection.
### Example: Logger Middleware
```rust
pub fn logger(req: &Request, next: &dyn Fn(&Request) -> Response) -> Response {
println!("๐ฅ {} {}", req.method(), req.url());
let res = next(req);
println!("๐ค Responded with {}", res.status_code());
res
}
```
- Middleware is synchronous and composable
- Multiple middleware are executed in registration order
- Built-in `logger` middleware is available in `velto::middleware`
---
## ๐ LiveReload
Velto automatically watches your `static/` and `templates/` directories in dev mode.
When a file changes, connected browsers reload instantly via WebSocket.
No setup required. Just call:
```rust
app.enable_dev_mode();
```
---
## ๐งช Testing
Velto includes a built-in `TestRequest` type for simulating requests in unit tests:
```rust
#[test]
fn test_homepage() {
let mut app = App::new();
route!(app, "/" => |_req| {
Response::from_string("Hello, test!")
});
let res = velto::test::TestRequest::new("GET", "/").send(&app);
assert_eq!(res.status_code(), 200);
assert!(res.body().contains("Hello"));
}
```
No external test harness required โ just write Rust tests and run `cargo test`.
---
## ๐งฐ Project Structure
Velto is organized into modular components for clarity and maintainability:
```
velto/
โโโ src/
โ โโโ app.rs # Core application logic
โ โโโ dev.rs # Dev mode toggles and helpers
โ โโโ form.rs # Form data parsing
โ โโโ http_method.rs # HTTP method utilities
โ โโโ macros.rs # Macros for render! and route!
โ โโโ middleware.rs # Middleware system and built-in examples
โ โโโ prelude.rs # Public API surface
โ โโโ reload.rs # LiveReload WebSocket + file watcher
โ โโโ response.rs # HTTP response utilities including redirect helpers
โ โโโ router.rs # Routing and handler dispatch
โ โโโ template.rs # Templating engine with include/inheritance
โ โโโ test.rs # TestRequest and internal test harness
โ โโโ util.rs # Utility functions (e.g., MIME types)
โ โโโ lib.rs # Entry point
```
---
## โ Why Velto
Velto is for developers who want:
- A fast, async-native web framework without the complexity of full-stack giants
- Clean routing and templating without ceremony
- Instant LiveReload for a smooth development loop
- A modular codebase that grows with your project
- A framework that feels like Rust โ not like a port of something else
Whether you're building a personal site, a microservice, or a dev tool, Velto gives you just enough structure to stay productive โ and just enough freedom to stay creative.
---
## ๐ Migration from 0.x
Velto 1.0.0 introduced async support and LiveReload, but kept the public API familiar. Here's what changed:
| `fn main()` | `#[tokio::main] async fn main()` |
| `Response<Cursor<Vec<u8>>>` | `Response` (no generics) |
| `app.run(...)` | `app.run(...).await` |
| No LiveReload | `app.enable_dev_mode()` |
Most route handlers and macros (`route!`, `render!`) remain unchanged.
Just update your `main()` function and remove `Cursor<Vec<u8>>` from response types.
---
## ๐ License
MIT โ free to use, modify, and distribute.
---
## ๐ฌ Contributing
Velto is evolving rapidly. If you have ideas, feedback, or want to help shape its future, open an issue or submit a PR.
We welcome clean code, thoughtful design, and good vibes.