Getting Started
Welcome to the Rullst Getting Started guide!
Your goal: install the matching v13 CLI, generate a small application, open it locally and make your first change. Prefer to write the first route yourself? Use Zero to Hello Rullst.
Rullst is a strictly typed Rust framework suite for full-stack applications, designed around explicit APIs, measurable performance, and defense-in-depth defaults.
1. Installation
First, ensure you have Rust installed. The official and recommended way is to visit rustup.rs.
For macOS and Linux:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
For Windows:
Download and run rustup-init.exe from the website.
Next, install the Rullst CLI from the same release train as the
framework. This book is built from main, where v13 is in development. The
v12 line reached end of life on 16 October 2026 (12.3.0 was its last release,
and a new 12.x project no longer resolves its dependencies after crates.io
yanked the zip releases its Studio needs), so install the v13 prerelease. Name its exact version: Cargo never selects a
prerelease on its own, so neither a plain cargo install cargo-rullst nor
^13 installs it:
cargo install cargo-rullst --version =13.0.0-alpha.4 --locked
Pin the framework the same way in Cargo.toml ("=13.0.0-alpha.4"); the
v13 migration guide explains why and what changed.
Source reviewers who intentionally need checkout-local changes can instead
clone this repository and install the CLI from that exact checkout. On main
this installs the v13 development CLI:
git clone --branch main https://github.com/Rullst/Rullst.git
cd Rullst
cargo install --locked --path cargo-rullst
cd ..
When installed from source, the CLI reuses the exact checkout from which it was compiled, even when project creation is invoked from another directory, provided that checkout has not been moved or deleted. Generated manifests therefore contain absolute path dependencies and are not portable. Running from the repository root remains an explicit fallback. Prefer the published prerelease and its matching registry packages for ordinary applications.
Cargo installs the cargo-rullst and rullst executables into
$CARGO_HOME/bin (~/.cargo/bin by default). To install elsewhere, set
CARGO_INSTALL_ROOT or pass --root <dir>. To remove the CLI, run:
cargo uninstall cargo-rullst
Add the same --root <dir> if you installed with one.
2. Creating Your First Project
Run the create wizard with the name of your application (or run
cargo rullst alone and choose Create New Project on its home screen):
cargo rullst new my_app
The wizard asks its questions in a terminal and writes nothing until you confirm. Esc goes back one question.
- Starter: Blank, API or SaaS, each with a one-line description and a preview of the files it generates (see Rullst Starters).
- Database: the primary database. SQLite is the simplest local first run; PostgreSQL, MySQL and MariaDB need their database service running.
- Features: optional features such as AI, Redis or a storage add-on. Selecting none is valid; a storage add-on is not another primary database.
- Review: the files and the commands it will run. Choose Create the project, Back to change an answer, or Cancel to exit without creating anything.
For a database-backed app, the CLI then compiles the new application once and
runs its initial migration, and prints three numbered next steps: cd my_app,
cargo rullst dev and the local URL of the generated welcome page, by default
http://127.0.0.1:3000:
cd my_app
cargo rullst dev
Open the local URL reported by the command. Find the generated page code,
change a heading and save. Confirm that the changed page appears after the
successful rebuild/restart. Stop development with Ctrl+C before moving or
removing the project directory.
cargo rullst new my_app --default --dry-run prints the plan, its file tree
and the commands without creating anything, and cargo rullst tour walks
through the main commands without changing a project. Without a terminal
(in CI or a script), new needs --default; flags such as --blueprint and
--database answer their questions. See the
CLI reference.
Prefer a small deterministic starter without navigating the wizard?
cargo rullst new first_app --default --blueprint blank --database sqlite \
--skip-initial-migration
cd first_app
cargo rullst dev
The first build compiles every dependency and can take several minutes
(about two and a half minutes for the Blank starter on the machine measured
in Build times, which also has tips). --skip-initial-migration
defers the generator’s bootstrap work; the development command runs the
initial migration before starting a generated database-backed app. Never point
this learning project at a production database.
Tip
The
cargo rullst devcommand compiles the project and starts the local server. Saving changes triggers a real rebuild and supervised process restart; a failed build leaves the previous application serving. The same-origin browser client refreshes after the new process responds with its generation marker. In-memory state resets. No hot-reload scaffold option is required. See the CLI reference.The CLI deliberately generates one audited application profile: Active Record with server-rendered
html!views and HTMX enhancement. The framework still exposes lower-level repository and client-runtime foundations for application-owned integration. See the Architecture Choices Guide.
3. Rullst Starters
cargo rullst new generates one of three starters. The wizard asks which one
(or pass --blueprint blank, api or saas); each uses the Rullst color
scheme and server-rendered HTML/HTMX patterns, and allocation and latency
depend on the generated page and runtime.
Blank
Use Case: Custom, from-scratch development.
This is the minimal template powered by server-rendered html! views and HTMX
without a project-local JavaScript bundle. It includes a simple reactive counter
to demonstrate server-driven communication. Other frontend foundations remain
available as application APIs, but are not advertised as equivalent generated
starters.
API
Use Case: Headless JSON services.
The Blank starter without HTML (--blueprint api, or --api): JSON routes, an
example write route protected by a bearer API_TOKEN written to .env, and
the same production security baseline. It can run without a database
(--no-database) or with Turso as its primary.
SaaS
Use Case: Subscription-based products and billing. An opinionated SaaS starting point, pre-wired with:
- User authentication (login, signup, session management, sign out
everywhere, password change and password reset by email with links built
from
RULLST_PUBLIC_ORIGIN). - Stripe pricing panels and subscription checkout views.
- Secure user dashboard and a Nexus admin for signed-in administrators.
Larger example applications
Up to 13.0.0-alpha.3 the CLI also generated LMS, Blog, Portfolio and ERP
starters. Since 13.0.0-alpha.4 they are complete applications in the repository’s
examples/ directory — examples/lms (courses, lessons, an
accessible player, enrollment and owner-bound progress), examples/erp
(products, stock and orders), examples/portfolio (a developer showcase edited
in Nexus) and the examples/blog showcase — tested in the workspace. Copy one
to start a bigger application; cargo rullst new --blueprint lms (or erp,
portfolio, blog) creates nothing and names the example instead.
Tip
Starter evolution: Starters are continuously checked by generator smoke tests. Treat generated code as an application starting point: inspect its configuration and rerun
cargo checkand security tests after customization.
Local Studio and Nexus access
The SaaS starter (and the LMS, ERP, Portfolio and Blog examples) expose visible buttons for both control surfaces during local development:
- Nexus is mounted at
/nexusand accepts only a verified loopback peer in a debug build, so the first local click needs no placeholder password. - Studio starts as a separate debug-only service at
http://127.0.0.1:5555.
This convenience cannot be enabled in a release binary through RULLST_ENV or
the legacy APP_ENV alias. A
release build does not start the generated Studio task, and Nexus needs a
real sign-in:
- SaaS (and the LMS example) admit the user signed in to the application whose
users.is_admincolumn is true, checked on every request; no extra credentials. Grant the first administrator with your database client (UPDATE users SET is_admin = TRUE WHERE email = '[email protected]';); that administrator can grant others from the Users model in Nexus. See using the application’s sign-in. - The Portfolio and ERP examples require unique
NEXUS_ADMIN_USERNAMEandNEXUS_ADMIN_PASSWORDvalues (Basic Auth behind verified TLS). Without them the application starts without/nexus(the ERP without its back office) and prints one line naming the missing variable; see serving the application without Nexus. The blog example needs the same variables in a release build and does not start without them.
Put production Nexus behind a verified TLS boundary; do not expose Studio publicly. Studio has no production mode: it runs only in debug builds and on loopback.
4. Database configuration and specialized stores
The wizard deliberately makes two separate decisions:
- Choose the primary SQLx Active Record backend: SQLite,
PostgreSQL, MySQL, or MariaDB. MariaDB uses the MySQL wire
protocol but has its own executable container contract. The Blank starter
(web page or JSON API) can instead select Turso/libSQL as its primary
database, through a separate adapter that has no Nexus, Studio database
pages,
Schemamigrations,artisan!or SQLx query builder. - Optionally add side stores: Turso/libSQL edge SQL, MongoDB documents, DuckDB analytics, SurrealDB documents/graph reads, Qdrant vectors or Redis structures. They use their own APIs and do not replace the primary pool.
Database Support lists what each backend works with; read it before you choose.
After generation, the default flow compiles the new application once and runs
its initial migration. A clean first build can take several minutes for the
larger SaaS starter. Use --skip-initial-migration when the network database is not yet
configured, then run cargo rullst db:migrate from the generated project.
cargo rullst dev applies pending migrations when it starts, but a deployed
server never does: run the binary’s db:migrate command on each release, as
described in Before the first deploy.
The non-interactive flags mirror the second step:
cargo rullst new edge_app --default --database mariadb --turso --mongodb \
--skip-initial-migration
Automation can pin the supported starter, database and optional runtime
capabilities. The application architecture is intentionally fixed to Active
Record plus server-rendered html!/HTMX:
cargo rullst new subscriptions --default --blueprint saas \
--database postgres --ai \
--skip-initial-migration
For a blank application with no primary relational database, use the explicit
--no-database flag. It cannot be combined with --database.
Generated SQLx profiles disable the default features of Rullst’s umbrella and
rullst-orm dependencies and select exactly one strict relational backend, so
a chosen PostgreSQL/MySQL/MariaDB profile is not accidentally compiled through
an implicit SQLite default.
To create a Turso-primary API using the current bounded blank starter:
cargo rullst new edge_app --default --api --database turso \
--skip-initial-migration
cd edge_app
cargo rullst db:migrate
The generated .env selects a persistent, real-SQL offline fallback and does
not invent a SQLx DATABASE_URL:
TURSO_DATABASE_URL=mock_local
TURSO_AUTH_TOKEN=
TURSO_OFFLINE_PATH=turso-development.db
To use Turso Cloud, put the token in its own variable rather than in the URL:
turso db create my-app-db
turso db tokens create my-app-db
TURSO_DATABASE_URL=libsql://my-app-db-username.turso.io
TURSO_AUTH_TOKEN=replace-with-a-secret-token
The familiar derive explicitly selects the Turso backend:
#![allow(unused)]
fn main() {
#[derive(Debug, Clone, rullst_orm::Orm)]
#[orm(table = "users", backend = "turso")]
struct User {
id: i64,
name: String,
}
}
User::all(), find, save, create, delete, count, filtering,
ordering and pagination then execute through the primary TursoOrm store.
make:model --migration, make:migration, db:migrate, db:status, and
db:rollback preserve this backend. The current first-class scaffold contract
is deliberately limited to the Blank and API starters; the SQLx-specific SaaS
starter rejects --database turso until ported.
Transparent embedded-replica synchronization is not claimed.
TursoStore remains available for prepared SQL, bounded result
materialization, transactions and checksummed migrations in either primary or
additive configurations.
See Polyglot Persistence for complete setup,
security constraints and examples for every optional store.