rust
Skill0 starsChanged 8 months agoMITView on GitHub
Mandatory guardrails for writing idiomatic, production-quality Rust code. This skill enforces zero-tolerance rules for unwrap()/expect(), correct thiserror vs anyhow usage, ownership and borrowing best practices, visibility minimalism (pub(crate) by default), and idiomatic patterns like the Entry API. Consult this skill for ANY task that writes, modifies, reviews, or refactors Rust code — including .rs files, Cargo.toml edits, CLI tools, libraries, error handling rewrites, and porting code to Rust. It catches the recurring mistakes that LLM-generated Rust makes and produces code that passes clippy and looks like it was written by someone who ships Rust in production.
38 other projects use a version of this.
Adopted by
Most recently taken up by
- elodin-sys/elodintheir own version, first seen Nov 9, 2026
- crbnos/carbontheir own version, first seen Nov 7, 2026
- lawless-m/claude-skillstheir own version, first seen Nov 6, 2026
- inference-gateway/skillstheir own version, first seen Nov 5, 2026
- alexjmiller5/agent-config-publictheir own version, first seen Nov 1, 2026
- its-ash/skillstheir own version, first seen Nov 1, 2026
Used with
Projects with it also use java, node and 9 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
testdino-hqSkilljava
Google's official Java style guide. Covers 2-space indentation, 100-char line limit, naming conventions, braces, imports, Javadoc, exception handling, lambdas, and streams. Enforces @Override annotations and specific imports.
Also in 4 projects that use this
mcollinaSkillnode
Provides domain-specific best practices for Node.js development with TypeScript, covering type stripping, async patterns, error handling, streams, modules, testing, performance, caching, logging, and more. Use when setting up Node.js projects with native TypeScript support, configuring type stripping (--experimental-strip-types), writing Node 22+ TypeScript without a build step, or when the user mentions 'native TypeScript in Node', 'strip types', 'Node 22 TypeScript', '.ts files without compilation', 'ts-node alternative', or needs guidance on error handling, graceful shutdown, flaky tests, profiling, or environment configuration in Node.js. Helps configure tsconfig.json for type stripping, set up package.json scripts, handle module resolution and import extensions, and apply robust patterns across the full Node.js stack.
Also in 3 projects that use this
rogue-dev-studioSkillpython
Python 3.13 with uv package manager via mise. Use when the project needs this capability or the user / team manifest asks for it. Use for specialized `python` work when listed in TEAM.yaml or explicitly requested.
Also in 6 projects that use this
rogue-dev-studioSkillgolang
Go development environment. Use when the project needs this capability or the user / team manifest asks for it. Use for specialized `golang` work when listed in TEAM.yaml or explicitly requested.
Also in 3 projects that use this
trotsky1997Skillast-grep
Guide for writing ast-grep rules to perform structural code search and analysis. Use when users need to search codebases using Abstract Syntax Tree (AST) patterns, find specific code structures, or perform complex code queries that go beyond simple text search. This skill should be used when users ask to search for code patterns, find specific language constructs, or locate code with particular structural characteristics.
Also in 3 projects that use this
OpenAISkillnextjs
Next.js App Router expert guidance. Use when building, debugging, or architecting Next.js applications — routing, Server Components, Server Actions, Cache Components, layouts, middleware/proxy, data fetching, rendering strategies, and deployment on Vercel.
Also in 3 projects that use this
Other versions38 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 38
- ccusage/ccusage★ 19ksame name
- ryoppippi/ccusage★ 19ksame name
- microsoft/fast★ 9.7ksame name
- pgdogdev/pgdog★ 5.6ksame name
- crbnos/carbon★ 2.8ksame name
- elodin-sys/elodin★ 553same name
- Mindrally/skills★ 275same name
- Moosync/Moosync★ 264same name
- wado-lang/wado★ 120same name
- databricks-solutions/apx★ 91same name
28 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository2 other files it gives its agents.
- nodejsSkill
- typescriptSkill
The file
We split this skill into the rules it gives an agent
2 rules. 0 are common, 0 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 31 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Use
Cow<'_, str>: when a function might or might not need to allocate — this avoids forcing the caller to allocate when they already have … - Very specific: line 53
Prefer
impl Traitoverdyn Trait: when the concrete type is known at compile time — monomorphization gives better performance and the …
“Common” is measured: kept by at least 6 in 10 of the 31 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Rust Guardrails
These guardrails apply to all Rust code you write, review, or modify. They exist because LLM-generated Rust tends to repeat the same classes of mistakes: lazy unwrap() calls, unnecessary cloning, overly broad visibility, and sloppy dependency management. Following these rules produces code that compiles cleanly, passes clippy, and looks like it was written by someone who actually ships Rust in production.
Error Handling
Rust's error handling is one of its greatest strengths — but only when used properly. The ? operator exists so you don't have to write boilerplate match arms, and crates like thiserror and anyhow exist so you don't have to hand-roll Display and Error impls.
- Never use
unwrap()orexpect()in production code. These are fine in tests and examples where a panic is acceptable, but in library or application code they're a ticking time bomb. Use?to propagate, or handle the error explicitly. - Always define structured error types with
thiserrorfirst. Every module that can fail should have its own error enum with#[derive(Debug, Error)]and#[error(...)]variants. This gives callers something to pattern-match on and produces clear error messages.thiserroris the right choice for both libraries and applications — the distinction is about whereanyhowfits in, not whether to define error types. - Use
anyhowonly at the application boundary — inmain(), CLI entry points, or top-level orchestration where you're collecting errors from multiple subsystems and just need to report them.anyhow::Resultwraps yourthiserrortypes; it never replaces them. If you find yourself writinganyhow::Resulton an internal function, stop and define a proper error type instead. - Propagate errors with
?— don't writematch result { Ok(v) => v, Err(e) => return Err(e) }whenresult?does the same thing. - Add context with
.context()/.with_context()fromanyhowat the boundary, or usemap_errto convert between yourthiserrortypes deeper in the stack.
Ownership & Borrowing
Unnecessary cloning is the most common sign of "fighting the borrow checker" — it compiles, but it's wasteful and hides design problems. Think about whether a function actually needs to own data before taking it by value.
- No unnecessary
clone()— if you clone, add a comment explaining why (e.g.,// clone needed: value used after move into spawned task). - Prefer
&Tover ownedTin function parameters unless the function genuinely needs ownership (e.g., storing the value in a struct, moving it into a thread). - Use
Cow<'_, str>when a function might or might not need to allocate — this avoids forcing the caller to allocate when they already have a&str. - Prefer
&stroverStringin function parameters. If the caller has aString, they can pass&s; the reverse isn't free. - Prefer
impl Iteratororimpl IntoIteratoroverVecin function parameters — this lets callers pass any iterator without collecting first.
Visibility
Rust defaults to private for good reason. Every pub item is a commitment — it's part of your API surface and can't be removed without a breaking change.
- Minimum visibility by default — use
pub(crate)instead ofpubunless the item is genuinely part of the public API. Leave items private when they don't need to be accessed outside their module. #[must_use]on all functions returningResultorOption— a silently ignored error is a bug waiting to happen.#[non_exhaustive]on public enums and structs that might grow — this lets you add variants or fields without breaking downstream code.
Patterns
- Edition 2021 minimum — there's no reason to target older editions in new code.
#[derive(Debug)]on all types — everything should be debuggable. AddClone,PartialEq,Eq,Hashetc. when semantically appropriate.- Prefer exhaustive
matchover wildcard_— when you enumerate all variants explicitly, the compiler tells you when a new variant is added. Use_only when the set is truly open-ended or when matching on values like integers/strings. - Use
if let/let elseovermatchfor single-variant checks —if let Some(x) = val { ... }is cleaner than a fullmatchwith a_ => {}arm. - Use
HashMap::entry()for insert-or-get patterns — never writeif !map.contains_key(&k) { map.insert(k, v); }whenmap.entry(k).or_insert_with(|| v)does the same thing in one lookup instead of two. The Entry API is also the right tool for counters (*entry.or_insert(0) += 1), default values, and conditional insertion. It's more efficient and signals intent clearly. - Builder pattern for structs with more than 3 fields — constructors with many positional arguments are error-prone and hard to read.
- Prefer
impl Traitoverdyn Traitwhen the concrete type is known at compile time — monomorphization gives better performance and the code is often simpler.
Dependencies
Bad dependency choices haunt a project for years. A few minutes of due diligence saves a lot of pain.
- Prefer well-maintained, widely-used crates:
serde,tokio,tracing,clap,thiserror,anyhow. These have large userbases, good docs, and responsive maintainers. - No yanked or deprecated crates — check before adding a dependency.
- Pin major versions in Cargo.toml — write
tokio = "1"nottokio = "*". Wildcard versions invite breakage. - Use
smol-tomlfor TOML parsing unless you need to preserve formatting/comments during editing (in which casetoml_editis appropriate). Avoid thetomlcrate —smol-tomlis lighter and faster. - Disable default features and enable only what's needed — e.g.,
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros"] }. This keeps compile times and binary size down.
Formatting & Style
cargo fmtcompliant — never fight rustfmt. If a formatting choice feels wrong, it's still better than inconsistency across the codebase.cargo clippyclean — no#[allow(clippy::...)]unless you have a genuine reason, documented with a comment explaining why the lint doesn't apply.- Doc comments (
///) on all public items — types, functions, methods, constants. Explain what it does and when to use it, not how it works internally. - Module-level doc comment (
//!) inlib.rs— this becomes the crate-level documentation.
Unsafe
Rust's safety guarantees are its core value proposition. unsafe should be a last resort, not a convenience.
- No
unsafeunless absolutely necessary — and "the safe version is slightly slower" is almost never a valid reason. - Every
unsafeblock must have a// SAFETY:comment explaining the invariant that makes this safe. This isn't optional — it's how you prove to reviewers (and your future self) that the code is sound.
Testing
#[cfg(test)]module in the same file for unit tests — keep tests close to the code they test.- Integration tests in
tests/directory — these test public API behavior from the outside. - Use
assert_eq!/assert_ne!overassert!(x == y)— the former gives you the actual vs. expected values on failure, which makes debugging far easier. - Test error cases, not just the happy path — if a function returns
Result, write tests that verify the error variants too.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

