rust-best-practices

Development guidance for writing idiomatic Rust. Use when: (1) writing new Rust functions or modules, (2) choosing between borrowing, cloning, or ownership patterns, (3) implementing error handling with Result types, (4) optimizing Rust code for performance, (5) configuring clippy and linting for a project, (6) deciding between static and dynamic dispatch, (7) writing documentation or doc tests.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rust-best-practices" with this command: npx skills add anderskev/rust-best-practices

Rust Best Practices

Guidance for writing idiomatic, performant, and safe Rust code. This is a development skill, not a review skill -- use it when building, not reviewing.

Quick Reference

TopicKey RuleReference
OwnershipBorrow by default, clone only when you need a separate owned copyreferences/coding-idioms.md
ClippyRun cargo clippy -- -D warnings on every commit; configure workspace lintsreferences/clippy-config.md
PerformanceDon't guess, measure. Profile with --release firstreferences/performance.md
GenericsStatic dispatch by default, dynamic dispatch when you need mixed typesreferences/generics-dispatch.md
Type StateEncode state in the type system when invalid operations should be compile errorsreferences/type-state-pattern.md
Documentation// for why, /// for what and how, //! for module/crate purposereferences/documentation.md
PointersChoose pointer types based on ownership needs and threading modelreferences/pointer-types.md
API DesignUnsurprising, flexible, obvious, constrained -- encode invariants in typesreferences/api-design.md
EcosystemEvaluate crates, pick error handling strategy, stay currentreferences/ecosystem-patterns.md

Gates

Short sequences with pass conditions before claiming outcomes that need evidence (not an internal “I checked”).

Clippy clean

  1. From the workspace root (or with -p <crate>), run: cargo clippy --all-targets --all-features -- -D warnings.
  2. Pass: exit status is 0 and the invocation finishes without Clippy-deny failures.

Performance claim

  1. Build with cargo build --release (or your benchmark harness) under the same profile you ship or measure.
  2. Capture a before and after number from the same tool and metric (name both), e.g. Criterion ns/iter, heaptrack allocations, or a flamegraph path on disk.
  3. Pass: you can cite both measurements, or you explicitly state that only correctness or readability changed and you are not claiming a performance delta.

Docs for symbols you changed

  1. Run cargo doc --no-deps for the crate you edited (add -p <crate> in workspaces).
  2. Pass: the doc build succeeds; if #![deny(missing_docs)] (or crate policy) applies, there are no new missing-doc errors for those symbols.

Coding Idioms

Prefer &T over .clone(), use &str/&[T] in parameters, and chain iterators instead of index-based loops. For Option/Result, use let Ok(x) = expr else { return } for early returns and ? for propagation. See references/coding-idioms.md for ownership, iterator, and import patterns.

Error Handling

Return Result<T, E> for fallible operations. Use thiserror for library error types, anyhow for binaries. Propagate with ?, never unwrap() outside tests. See references/coding-idioms.md for Option/Result patterns.

Clippy Discipline

Run cargo clippy --all-targets --all-features -- -D warnings on every commit. Configure workspace lints in Cargo.toml and use #[expect(clippy::lint)] (not #[allow]) as the standard for lint suppression -- it warns when the suppression becomes stale. See references/clippy-config.md for lint configuration and key lints.

Performance Mindset

Always benchmark with --release, profile before optimizing, and avoid cloning in loops or premature .collect() calls. Keep small types on the stack and heap-allocate only recursive structures and large buffers. See references/performance.md for profiling tools and allocation guidance.

Generics and Dispatch

Use static dispatch (impl Trait / <T: Trait>) by default for zero-cost monomorphization. Switch to dyn Trait only for heterogeneous collections or plugin architectures, preferring &dyn Trait over Box<dyn Trait> when ownership isn't needed. In edition 2024, -> impl Trait captures all in-scope lifetimes by default -- use + use<'a, T> for precise capture control. Prefer native async fn in traits over the async-trait crate for static dispatch. See references/generics-dispatch.md for dispatch trade-offs, RPIT capture rules, and async trait guidance.

Type State Pattern

Encode valid states in the type system so invalid operations become compile errors. Use for builders with required fields, protocol state machines, and workflow pipelines. See references/type-state-pattern.md for implementation patterns and when to avoid.

Documentation

Use // for why, /// for what/how on public APIs, and //! for module purpose. Every TODO needs a linked issue and library crates should enable #![deny(missing_docs)]. Use #[diagnostic::on_unimplemented] to provide custom compiler errors for your public traits. See references/documentation.md for doc test patterns, comment conventions, and diagnostic attributes.

API Design

Follow four principles: unsurprising (reuse standard names and traits), flexible (use generics and impl Trait to avoid unnecessary restrictions), obvious (encode invariants in the type system so misuse is a compile error), and constrained (expose only what you can commit to long-term). Use #[non_exhaustive] for types that may grow, seal traits you need to extend without breaking changes, and wrap foreign types in newtypes to control your SemVer surface. See references/api-design.md for builder patterns, sealed traits, and SemVer implications.

Ecosystem Patterns

Evaluate crates by recent download trends, maintenance activity, documentation quality, and transitive dependency weight. Use thiserror for library error types, anyhow for binaries, and eyre when you need custom error reporters. Prefer vendoring or writing code yourself when a crate pulls heavy dependencies for a small feature. Run cargo-deny for license and vulnerability auditing and cargo-udeps to trim unused dependencies. See references/ecosystem-patterns.md for crate evaluation criteria, edition migration, and essential tooling.

Pointer Types

Choose pointer types based on ownership and threading: Box<T> for single-owner heap allocation, Rc<T>/Arc<T> for shared ownership, Cell/RefCell/Mutex/RwLock for interior mutability. Use LazyLock/LazyCell (stable since 1.80) instead of lazy_static or once_cell. See references/pointer-types.md for the full single-thread vs multi-thread decision table and migration guidance.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Claude Chrome

Use Claude Code with Chrome browser extension for web browsing and automation tasks. Alternative to OpenClaw's built-in browser tools.

Registry SourceRecently Updated
Coding

App Builder

Build, edit, and deploy Instant-backed apps using npx instant-cli, create-instant-app (Next.js + Codex), GitHub (gh), and Vercel (vercel). Use when asked to create a new app, modify an existing app, fix bugs, add features, or deploy/update an app. Projects live under ~/apps; always work inside the relevant app folder.

Registry SourceRecently Updated
Coding

Opengraph Io

Extract web data, capture screenshots, scrape content, and generate AI images via OpenGraph.io. Use when working with URLs (unfurling, previews, metadata), capturing webpage screenshots, scraping HTML content, asking questions about webpages, or generating images (diagrams, icons, social cards, QR codes). Triggers: 'get the OG tags', 'screenshot this page', 'scrape this URL', 'generate a diagram', 'create a social card', 'what does this page say about'.

Registry SourceRecently Updated
Coding

Xlsx Pro

Compétence pour manipuler les fichiers Excel (.xlsx, .xlsm, .csv, .tsv). Utiliser quand l'utilisateur veut : ouvrir, lire, éditer ou créer un fichier tableur ; ajouter des colonnes, calculer des formules, formater, créer des graphiques, nettoyer des données ; convertir entre formats tabulaires. Le livrable doit être un fichier tableur. NE PAS utiliser si le livrable est un document Word, HTML, script Python standalone, ou intégration Google Sheets.

Registry SourceRecently Updated
2.1K0Profile unavailable
rust-best-practices | V50.AI