Cot · build a Django-style web app in Rust (project → model → admin)

3 months ago

Building a web app in Rust usually means wiring up a web server, a database layer, templates, and authentication yourself. Cot is the batteries-included alternative: think Django, but in Rust. It is built on axum, and it hands you the whole stack in one box.

Ask

Ask about this presentation

Answers are generated from this presentation.

Chapters

  1. 0:00Slide 1
  2. 0:16Install and scaffold
  3. 0:32Views and routing
  4. 0:48A model is a Rust struct
  5. 1:01Migrations, generated for you
  6. 1:12An admin panel for free
  7. 1:30The Django workflow, in Rust
Show transcript

Slide 1

Cot logo

A batteries-included, Django-inspired web framework for Rust.

cot new → #[model] → admin panel

Building a web app in Rust usually means wiring up a web server, a database layer, templates, and authentication yourself. Cot is the batteries-included alternative: think Django, but in Rust. It is built on axum, and it hands you the whole stack in one box.

Install and scaffold

cargo install --locked cot-cli
cot new cot_tutorial
cot_tutorial
├── config       # dev.toml, prod.toml.example
├── src          # main.rs, migrations.rs
├── static       # css/main.css
├── templates    # index.html
├── bacon.toml
└── Cargo.toml

Ready to run · bacon serve for live reload · welcome page at localhost:8000.

Install the command-line tool with one Cargo command, then create a project with cot new. You get a complete project: config, source, static files, and templates, ready to run. Start it with bacon serve and open localhost on port 8000 to see your welcome page.

Views and routing

async fn index() -> cot::Result<Html> {
    let index_template = IndexTemplate {};
    let rendered = index_template.render()?;
    Ok(Html::new(rendered))
}
async fn hello_name(
    Path(name): Path<String>,
) -> cot::Result<Html> {
    Ok(Html::new(format!("Hello, {}!", name)))
}

A typed Path extractor · checked at compile time.

A view is just an async function that returns some HTML. You register it on a route with a path and a name. Need a dynamic segment in the URL? Add a typed path extractor. The value comes back as a real Rust string, checked at compile time, instead of parsed by hand.

A model is a Rust struct

use cot::db::{model, Auto, LimitedString};

#[model]
pub struct Link {
    #[model(primary_key)]
    id: Auto<i64>,
    #[model(unique)]
    slug: LimitedString<32>,
    url: String,
}

Your Rust types are the source of truth · no separate schema files to keep in sync.

Here is where Cot shines. A database model is a plain Rust struct with one attribute on top. Your Rust types are the source of truth: a primary key, a unique slug, a link. There are no separate schema files to keep in sync by hand.

Migrations, generated for you

cot migration make

Cot reads the struct and writes the migration · no hand-written SQL · change a field, run it again.

When your struct changes, you do not write SQL. Run cot migration make, and Cot generates the migration for you, straight from the struct. Change a field, run it again, and your database schema keeps up automatically.

An admin panel for free

apps.register(DatabaseUserApp::new());
apps.register_with_views(AdminApp::new(), "/admin");
// + .middleware(SessionMiddleware::new())
#[derive(Debug, Form, AdminModel)]
#[model]
struct Link { /* ... */ }

Seed an admin user · then browse, add, edit, delete at /admin · no custom views.

Now the payoff. Register the admin app and a session, seed an admin user, then add one derive to your model and register it. That is it. You get a full admin panel, right in your browser, where you can browse, add, edit, and delete every model you register. No custom views, no templates.

The Django workflow, in Rust

  • Scaffold · cot new gives you a runnable project.
  • Model · a plain struct is your schema, migrations generated.
  • Admin · full add / edit / delete at /admin.
  • Type-safe, secure by default · built on axum.

cargo install --locked cot-cli  ·  cot.rs

That is the Django workflow, with Rust's type safety and speed: scaffold a project, define a model, get an admin panel, all secure by default. Install cot-cli, run cot new, and read the guide at cot dot R S. Give it a try.