Introduction
Welcome to Soli, a dynamically-typed, high-performance web framework and programming language written in Rust. Soli combines the expressiveness of Ruby with a batteries-included MVC stack — 170,000+ requests/second and sub-millisecond response times, powered by a bytecode VM.
What you'll learn
This guide tours Soli's full feature surface — language, web framework, database, realtime, and tooling — then gets you from zero to a running app in three commands.
What is Soli?
Soli is two things in one: a dynamically-typed language with optional type annotations, and a batteries-included MVC web framework built on top of it. No compile step gates execution — but soli check will static type-check the parts you've annotated.
requests/second, single server
typical response times
from install to running app
Feature Tour
A map of what Soli ships with. Each group links to the full deep-dive.
Language
Dynamic + optional types
Write fast, annotate where it pays off — runtime checks, IDE support, docs.
Classes & interfaces
Familiar OOP with inheritance — class Foo < Bar.
Pattern matching
match with guards and destructuring.
Enums
First-class enumerated types.
Closures & pipelines
fn(x) {}, |x| {}, and the |> pipeline operator.
Error handling
try/catch/finally plus postfix rescue.
Modern conveniences
String interpolation, ??, &., spread/rest, named params.
Metaprogramming
define_method, method_missing, and more.
Web Framework
Convention over configuration
Autoloaded controllers, models, services, policies, jobs, mailers.
Declarative routing
resources(), nesting, namespaces, named route helpers.
ERB-style views
.html.slv templates with layouts and partials.
Middleware pipeline
Request/response interceptors for auth, CORS, logging.
Data & Persistence
SoliDB
Built-in document database, queried with AQL.
Active-Record-style Model API
find, where, order, create, update.
Relationships
belongs_to, has_many, has-and-belongs-to-many.
Validations, migrations & more
Callbacks, state machines, query scopes.
Realtime
WebSockets
First-class bidirectional connections.
Live View
Server-rendered reactive components — no client JS needed.
Streaming / SSE
Push updates to the browser as they happen.
Batteries Included
Auth & security
JWT auth, policy-based authorization, CSRF, XSS sanitization, Argon2, secure cookies.
Sessions
Four pluggable backends: in-memory, disk, SoliDB, or SoliKV.
Jobs & cron
perform_later, perform_in, perform_at, scheduled jobs.
Mailer
HTML/text emails, attachments, SMTP delivery.
Document generation
PDF rendering, including Factur-X/EN16931 e-invoicing.
i18n
Multi-locale support out of the box.
Developer Tools
Hot reload
Edit and refresh — no restart needed.
Beautiful dev error pages
Variable inspection right in the browser.
Scaffold generator
soli generate scaffold builds a full resource in seconds.
Built-in package manager
soli add / install / publish against a registry, via soli.toml.
Lint, format, type-check
soli lint, soli fmt, soli check.
LSP + editor integration
Language server and VS Code extension.
BDD testing framework
describe/test, HTTP integration tests, coverage reporting.
The MVC Pattern
Soli follows the Model-View-Controller (MVC) architectural pattern, separating your app into three layers:
Model
Manages data, business logic, and database interactions. Located in app/models/.
View
Handles the presentation layer and HTML templates. Located in app/views/.
Controller
Coordinates between Models and Views to handle requests. Located in app/controllers/.
Quick Start
# Install the Soli CLI
curl -sSL https://raw.githubusercontent.com/solisoft/soli_lang/main/install.sh | sh
# Scaffold a new app
soli new my_app
cd my_app
# Start the dev server (auto-compiles Tailwind CSS, hot reload enabled)
soli serve . --dev
That's it
Your app is live at http://localhost:5011. No npm install required to get started — --dev mode compiles your Tailwind CSS for you.
Project Structure
my_app/
├── app/
│ ├── controllers/ # Request handlers
│ │ └── home_controller.sl
│ ├── jobs/ # Background jobs
│ ├── middleware/ # Request interceptors
│ ├── views/ # HTML templates
│ │ ├── layouts/ # Shared layouts
│ │ │ └── application.html.slv
│ │ └── home/
│ │ └── index.html.slv
│ └── assets/
│ └── css/ # Tailwind source
├── config/
│ ├── routes.sl # Route definitions
│ ├── application.sl # App configuration
│ └── locales/ # i18n translation files
├── public/
│ └── css/ # Compiled CSS output
└── package.json # Tailwind toolchain (only needed if customizing)
Quick Example
Here's how the pieces fit together in a simple Soli application:
1 Define a Route
get("/", "home#index")
get("/users/:id", "users#show")
2 Create a Controller
class HomeController < Controller
def index
message = "Welcome to Soli!"
render("home/index", {
"title": "Home",
"message": message
})
end
end
3 Build a View
<h1><%= message %></h1>
<p>Start building something amazing.</p>
The Package Manager
Soli ships with a built-in package manager — no separate tool needed:
soli init # create soli.toml in the current directory
soli add utils --path ../shared/utils
soli add soli-math --version 1.0.0
soli install # install everything from soli.toml
soli publish # publish your package to a registry
The manifest can also pin a minimum interpreter version with soli_version = "1.16.0" in [package]; soli serve/test/run then refuse to start on an older soli.
See Modules & Packages for the full soli.toml reference.
Design Philosophy
Soli favors convention over configuration. By following standard naming patterns, you write less glue code and focus on building features.
Next Steps
Installation →
Get Soli running on your machine.
Configuration →
Environment variables for databases, sessions, jobs, and deployment.
Routing →
Learn how to define your application's URLs.
Language Reference →
The complete Soli syntax, types, and language features.
Models →
ORM-style data modeling with CRUD operations.
Deploy →
Ship to production with blue-green deployment.