Why Soli?
Soli is a full-stack MVC framework written in Rust that brings the elegance of Ruby/Rails to the performance of systems programming. Build web applications with expressive, readable code while enjoying sub-millisecond response times.
// Define a controller
fn index(req: Any) -> Any {
let posts = Post
.where("doc.published == true")
.order("created_at", "desc")
.limit(10)
.all();
return render("posts/index", {
"title": "Latest Posts",
"posts": posts
});
}
Features
Performance
- 170,000+ requests/second on a single server
- Sub-millisecond response times for most requests
- Zero-copy JSON parsing and efficient memory management
- Bytecode compilation for fast execution
Developer Experience
- Hot reload - See changes instantly without restart
- Beautiful error pages with variable inspection in dev mode
- Scaffold generator - Generate complete MVC resources in seconds
- Convention over configuration - Sensible defaults, less boilerplate
Full-Stack Features
- ERB-style templates with layouts and partials
- Active Record ORM with migrations, validations, and relationships
- WebSocket support with Live View for reactive UIs
- Built-in authentication with JWT and session management
- i18n support for multi-language applications
- Tailwind CSS integration with automatic compilation
Security
- CSRF protection
- XSS sanitization
- Secure session cookies
- Input validation helpers
Quick Start
Installation
# Clone the repository
# Build the release binary
# Add to PATH (optional)
Create a New Project
# Generate a new MVC application
# Install frontend dependencies (for Tailwind CSS)
# Start the development server
Visit http://localhost:5011 to see your app!
Generate a Resource
# Generate a complete blog posts scaffold
# Run migrations
This creates:
- Model with validations
- Controller with CRUD actions
- Views (index, show, new, edit)
- Database migration
- Test files
- Routes configuration
Project Structure
my_app/
├── app/
│ ├── controllers/ # Route handlers
│ ├── models/ # Data models with ORM
│ ├── views/ # ERB templates
│ │ └── layouts/ # Layout templates
│ ├── middleware/ # Request/response middleware
│ └── helpers/ # View helper functions
├── config/
│ ├── routes.sl # Route definitions
│ └── database.sl # Database configuration
├── db/
│ └── migrations/ # Database migrations
├── public/ # Static assets
├── tests/ # Test files
└── package.json # Frontend dependencies
Documentation
Full documentation is available at http://localhost:5011/docs when running the server, covering:
- Getting Started - Installation and first steps
- Core Concepts - Routing, controllers, middleware, views
- Database - Configuration, models, migrations
- Security - Authentication, sessions, validation
- Live View - Real-time reactive components
- Language Reference - Soli language syntax and features
- Built-in Functions - Complete API reference
Examples
Routing
// config/routes.sl
// Simple routes
get("/", "home#index");
get("/about", "home#about");
// RESTful resources
resources("posts");
resources("users");
// Nested resources
resources("posts", fn() {
resources("comments");
});
// Scoped middleware
middleware("authenticate", fn() {
get("/admin", "admin#index");
resources("admin/users");
});
// API namespace
namespace("api/v1", fn() {
resources("posts");
});
Models
class Post extends Model {
validates("title", { "presence": true, "min_length": 3 });
validates("content", { "presence": true });
fn author() -> Any {
return User.find(this.author_id);
}
fn comments() -> Any {
return Comment.where("doc.post_id == @id", { "id": this.id });
}
}
Controllers
fn create(req: Any) -> Any {
let params = req["params"];
let result = Post.create(params);
if result["valid"] {
return redirect("/posts/" + result["record"]["id"]);
}
return render("posts/new", {
"errors": result["errors"],
"post": params
});
}
Views
<!-- app/views/posts/index.html.slv -->
Read more
Live View
Build reactive UIs without writing JavaScript:
<!-- app/views/live/counter.sliv -->
@count
-
+
// app/controllers/live_controller.sl
fn counter(event: Any) -> Any {
let count = event["state"]["count"] ?? 0;
if event["event"] == "increment" {
count = count + 1;
} elsif event["event"] == "decrement" {
count = count - 1;
}
return { "state": { "count": count } };
}
Testing
Soli includes a comprehensive testing framework:
describe("PostsController", fn() {
before_each(fn() {
as_guest();
});
test("lists all posts", fn() {
let response = get("/posts");
assert_eq(res_status(response), 200);
});
test("creates post when authenticated", fn() {
login("user@example.com", "password");
let response = post("/posts", {
"title": "New Post",
"content": "Content here"
});
assert_eq(res_status(response), 201);
});
});
Run tests:
# Run all tests
# Run with coverage
# Run specific test file
Performance
Benchmarked on a standard server (16 cores):
| Metric | Value |
|---|---|
| Requests/sec | 172,409 |
| Avg Latency | 0.58ms |
| Transfer/sec | 23.01 MB |
IDE Support
VS Code Extension
Install the Soli language extension for VS Code:
Features:
- Syntax highlighting for
.sland.slivfiles - Code snippets
- Error diagnostics
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Inspired by Ruby on Rails, Phoenix Framework, and Laravel
- Built with Rust for performance and safety
- Uses ArangoDB for flexible document storage