/rust-dev
Practical day-1 guide to building applications in Rust well. Covers the mental model (ownership, errors as values, traits-not-interfaces), day-1 decisions (String vs &str, Box vs Rc vs Arc, dyn vs impl Trait, anyhow vs thiserror), idioms to internalize early, anti-patterns to
$ npx -y skills add tenequm/skills --skill rust-dev --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/rust-dev
Context preview
The summary Claude sees to decide when to auto-load this skill.
Practical day-1 guide to building applications in Rust well. Covers the mental model (ownership, errors as values, traits-not-interfaces), day-1 decisions (String vs &str, Box vs Rc vs Arc, dyn vs impl Trait, anyhow vs thiserror), idioms to internalize early, anti-patterns to
SKILL.md
rust-dev.SKILL.mdname: rust-dev
description: Practical day-1 guide to building applications in Rust well. Covers the mental model (ownership, errors as values, traits-not-interfaces), day-1 decisions (String vs &str, Box vs Rc vs Arc, dyn vs impl Trait, anyhow vs thiserror), idioms to internalize early, anti-patterns to avoid, and a tight crate shortlist (tokio, serde, anyhow, clap, reqwest, tracing, axum, sqlx). Use when starting a new Rust project, learning Rust coming from Python/JS/Go/Java/C++, deciding on types and lifetimes, choosing crates, structuring modules, configuring Cargo.toml/clippy/rustfmt, writing tests, benchmarking, profiling, speeding up builds, or releasing and distributing a binary, or whenever the user mentions Rust, cargo, ownership, borrow checker, lifetimes, traits, async Rust, testing, or "writing this in Rust".
metadata:
version: "0.4.1"
upstream: "rust@1.95.0, axum@0.8.9, reqwest@0.13.3, sqlx@0.9.0, jiff@0.2.24, kache@0.9.0, dist@0.32.0, release-plz@0.5"
openclaw:
homepage: https://github.com/tenequm/skills/tree/main/skills/rust-dev
emoji: "๐ฆ"Rust Development - Day 1
A practical foundation for writing Rust apps well from the first commit. Not a textbook. Focuses on the differences from other languages, the day-1 decisions that shape everything else, and the small set of crates that cover most real apps.
When to Use
- Starting a new Rust project (CLI, service, library)
- Coming to Rust from Python, JavaScript, Go, Java/C#, or C++
- Choosing between owned/borrowed types, smart pointers, trait objects vs generics
- Picking error handling strategy (`anyhow` vs `thiserror`)
- Deciding which crates to reach for
- Configuring a minimal but opinionated `Cargo.toml`, clippy, and rustfmt
Day-1 Setup
# 1. Install the toolchain (rustup is the toolchain manager)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 2. Confirm components (rustfmt and clippy ship with stable, rust-src enables IDE features)
rustup component add rustfmt clippy rust-src
# 3. Create a project
cargo new my-app # binary (src/main.rs)
cargo new --lib my-lib # library (src/lib.rs)
# 4. The dev loop (memorize these four)
cargo check # fast type-check, no codegen
cargo run # build and run (binary)
cargo test # build and run tests (incl. doctests)
cargo clippy # lint (run before pushing)
cargo fmt # format
# 5. Manage dependencies without editing Cargo.toml by hand
cargo add tokio --features full
cargo remove tokio
cargo update # recompute Cargo.lock within existing semver ranges
`cargo update` only moves within the version ranges already in `Cargo.toml`. Crossing a major version (`1.x` to `2.0`) needs a `Cargo.toml` edit or `cargo add <crate>@2`.
**rust-analyzer is mandatory.** It is the language server every editor uses (VS Code, Zed, Neovim, Helix, RustRover uses its own engine but is comparable). In VS Code, install the `rust-analyzer` extension and set `rust-analyzer.check.command` to `"clippy"` so you get lint feedback on save.
**Want a file watcher later?** `cargo install bacon`, then run `bacon` in your project. Not needed on day 1.
The Rust Mental Model in 5 Ideas
Rust trades two things you take for granted in most languages (a garbage collector and exceptions) for compile-time guarantees about memory, data races, and error handling. The shape of the language follows from that trade.
1. Ownership: every value has exactly one owner
Think of values like physical objects. A book, a file, a network connection. At any moment, **one variable owns it**. You can:
- **Move it**: `let b = a;` hands ownership to `b`. `a` is gone.
- **Borrow it immutably**: `&a` lets others look at it. Many readers allowed.
- **Borrow it mutably**: `&mut a` lets one person modify it. Exclusive access.
- **Clone it**: `a.clone()` makes a deep copy. Both keep their own.
When the owner goes out of scope, the value is dropped (memory freed, file closed, lock released). No GC, no manual `free`. This is RAII, enforced by the compiler.
2. Aliasing XOR mutability
At any moment, a piece of data has **either**:
- one mutable reference (`&mut T`), **or**
- any number of immutable references (`&T`),
never both. This single rule is what eliminates data races and most use-after-free bugs. The borrow checker enforces it. When it complains, it is telling you your data ownership story is unclear, not that the language is being difficult.
3. Errors are values, not exceptions
There is no `try`/`catch`. Functions that can fail return `Result<T, E>`. Functions that can return nothing useful return `Option<T>`. The compiler forces you to handle both. The `?` operator propagates errors up the call stack with one character:
fn read_config() -> Result<Config, anyhow::Error> {
let text = std::fs::read_to_string("config.toml")?; // ? = early-return on Err
let config = toml::from_str(&text)?;
Ok(config)
}There is no `null`. `Option<T>` is `None` or `Some(value)`. The compiler will not let you forget the `None` case.
4. Traits are not Java interfaces
A `trait` defines behavior. Types `impl` traits. So far so familiar. The differences:
- **Static dispatch is the default.** When you write `fn f<T: Display>(x: T)`, the compiler generates a separate copy of `f` for each concrete `T` you call it with (monomorphization, like C++ templates). Zero runtime overhead.
- **Dynamic dispatch is opt-in** via `dyn Trait` (typically `Box<dyn Trait>` or `&dyn Trait`). One vtable lookup per call.
- **No inheritance.** Traits compose. If you find yourself reaching for `Deref` to "extend" a type, stop and use composition or an enum.
- **Orphan rule**: you can `impl YourTrait for SomeoneElsesType` or `impl SomeoneElsesTrait for YourType`, but not both foreign. This keeps dependency resolution sane.
5. The borrow checker is a design oracle
The most common newcomer mistake is treating compiler errors as ob
Read more
name: rust-dev
description: Practical day-1 guide to building applications in Rust well. Covers the mental model (ownership, errors as values, traits-not-interfaces), day-1 decisions (String vs &str, Box vs Rc vs Arc, dyn vs impl Trait, anyhow vs thiserror), idioms to internalize early, anti-patterns to avoid, and a tight crate shortlist (tokio, serde, anyhow, clap, reqwest, tracing, axum, sqlx). Use when starting a new Rust project, learning Rust coming from Python/JS/Go/Java/C++, deciding on types and lifetimes, choosing crates, structuring modules, configuring Cargo.toml/clippy/rustfmt, writing tests, benchmarking, profiling, speeding up builds, or releasing and distributing a binary, or whenever the user mentions Rust, cargo, ownership, borrow checker, lifetimes, traits, async Rust, testing, or "writing this in Rust".
metadata:
version: "0.4.1"
upstream: "rust@1.95.0, axum@0.8.9, reqwest@0.13.3, sqlx@0.9.0, jiff@0.2.24, kache@0.9.0, dist@0.32.0, release-plz@0.5"
openclaw:
homepage: https://github.com/tenequm/skills/tree/main/skills/rust-dev
emoji: "๐ฆ"Rust Development - Day 1
A practical foundation for writing Rust apps well from the first commit. Not a textbook. Focuses on the differences from other languages, the day-1 decisions that shape everything else, and the small set of crates that cover most real apps.
When to Use
- Starting a new Rust project (CLI, service, library)
- Coming to Rust from Python, JavaScript, Go, Java/C#, or C++
- Choosing between owned/borrowed types, smart pointers, trait objects vs generics
- Picking error handling strategy (`anyhow` vs `thiserror`)
- Deciding which crates to reach for
- Configuring a minimal but opinionated `Cargo.toml`, clippy, and rustfmt
Day-1 Setup
# 1. Install the toolchain (rustup is the toolchain manager) curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # 2. Confirm components (rustfmt and clippy ship with stable, rust-src enables IDE features) rustup component add rustfmt clippy rust-src # 3. Create a project cargo new my-app # binary (src/main.rs) cargo new --lib my-lib # library (src/lib.rs) # 4. The dev loop (memorize these four) cargo check # fast type-check, no codegen cargo run # build and run (binary) cargo test # build and run tests (incl. doctests) cargo clippy # lint (run before pushing) cargo fmt # format # 5. Manage dependencies without editing Cargo.toml by hand cargo add tokio --features full cargo remove tokio cargo update # recompute Cargo.lock within existing semver ranges
`cargo update` only moves within the version ranges already in `Cargo.toml`. Crossing a major version (`1.x` to `2.0`) needs a `Cargo.toml` edit or `cargo add <crate>@2`.
**rust-analyzer is mandatory.** It is the language server every editor uses (VS Code, Zed, Neovim, Helix, RustRover uses its own engine but is comparable). In VS Code, install the `rust-analyzer` extension and set `rust-analyzer.check.command` to `"clippy"` so you get lint feedback on save.
**Want a file watcher later?** `cargo install bacon`, then run `bacon` in your project. Not needed on day 1.
The Rust Mental Model in 5 Ideas
Rust trades two things you take for granted in most languages (a garbage collector and exceptions) for compile-time guarantees about memory, data races, and error handling. The shape of the language follows from that trade.
1. Ownership: every value has exactly one owner
Think of values like physical objects. A book, a file, a network connection. At any moment, **one variable owns it**. You can:
- **Move it**: `let b = a;` hands ownership to `b`. `a` is gone.
- **Borrow it immutably**: `&a` lets others look at it. Many readers allowed.
- **Borrow it mutably**: `&mut a` lets one person modify it. Exclusive access.
- **Clone it**: `a.clone()` makes a deep copy. Both keep their own.
When the owner goes out of scope, the value is dropped (memory freed, file closed, lock released). No GC, no manual `free`. This is RAII, enforced by the compiler.
2. Aliasing XOR mutability
At any moment, a piece of data has **either**:
- one mutable reference (`&mut T`), **or**
- any number of immutable references (`&T`),
never both. This single rule is what eliminates data races and most use-after-free bugs. The borrow checker enforces it. When it complains, it is telling you your data ownership story is unclear, not that the language is being difficult.
3. Errors are values, not exceptions
There is no `try`/`catch`. Functions that can fail return `Result<T, E>`. Functions that can return nothing useful return `Option<T>`. The compiler forces you to handle both. The `?` operator propagates errors up the call stack with one character:
fn read_config() -> Result<Config, anyhow::Error> {
let text = std::fs::read_to_string("config.toml")?; // ? = early-return on Err
let config = toml::from_str(&text)?;
Ok(config)
}There is no `null`. `Option<T>` is `None` or `Some(value)`. The compiler will not let you forget the `None` case.
4. Traits are not Java interfaces
A `trait` defines behavior. Types `impl` traits. So far so familiar. The differences:
- **Static dispatch is the default.** When you write `fn f<T: Display>(x: T)`, the compiler generates a separate copy of `f` for each concrete `T` you call it with (monomorphization, like C++ templates). Zero runtime overhead.
- **Dynamic dispatch is opt-in** via `dyn Trait` (typically `Box<dyn Trait>` or `&dyn Trait`). One vtable lookup per call.
- **No inheritance.** Traits compose. If you find yourself reaching for `Deref` to "extend" a type, stop and use composition or an enum.
- **Orphan rule**: you can `impl YourTrait for SomeoneElsesType` or `impl SomeoneElsesTrait for YourType`, but not both foreign. This keeps dependency resolution sane.
5. The borrow checker is a design oracle
The most common newcomer mistake is treating compiler errors as ob
Showing the first part of this file.
Claude Code skills for founders, developers, and web3 builders. This repository publishes reusable skill folders under skills//, ships stable bundle downloads through GitHub Releases, and publishes changed skills to ClawHub.
Repo: tenequm/skills
Other skills on tenequm-skills.
- /audio-quality-check
Analyze audio recording quality - echo detection, loudness, speech intelligibility, SNR, spectral analysis. Use when the user wants to check a recording's quality, detect echo or duplication in audio files, measure speech clarity, compare original vs processed audio, diagnose
Open skill - /chrome-extension-wxt
Build Chrome extensions using WXT framework with TypeScript, React, Vue, or Svelte. Use when creating browser extensions, developing cross-browser add-ons, or working with Chrome Web Store projects. Triggers on phrases like "chrome extension", "browser extension", "WXT
Open skill - /cloudflare-workers
Cloudflare account ID, set as a CI secret for wrangler deploys.
Open skill - /command-skill-creator
Create automation command skills (slash commands) for Claude Code projects. Use when building `/slash-commands` that automate multi-step workflows - deploys, commits, releases, migrations, cross-repo operations, or any repeatable process. Triggers on "create a command", "make a
Open skill - /deep-research-glim
Conducts deep, multi-angle research using glim MCP tools and parallel subagents. Use for deep research, competitive landscape analysis, strategic intelligence, or /deep-research-glim [topic]. Triggers - deep research, deep dive on, competitive landscape, strategic intelligence,
Open skill - /download-webpage-as-pdf
Set to "false" (the recipe default) to force headless capture regardless of the host agent-browser config
Open skill

