rust-backend

Applies Windmill-specific Rust coding patterns to backend code changes.

3|1|Updated Apr 29, 2026
One-click install
npx skills add https://github.com/firstsun-dev/skills --skill rust-backend-firstsun-dev
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: rust-backend
Source: https://github.com/firstsun-dev/skills/tree/main/plugins/software-delivery/skills/windmill-rust-backend
Command: npx skills add https://github.com/firstsun-dev/skills --skill rust-backend-firstsun-dev

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Writing Rust code in the Windmill backend requires following project-specific conventions for error handling, SQLx queries, JSON handling, and async patterns that generic Rust knowledge does not cover. ## Core Features & Use Cases - Error Handling Conventions: Enforces use of windmill_common::error::Error with Result<T, Error> returns and forbids panics in library code. - SQLx Query Patterns: Prevents SELECT * usage for backwards compatibility, promotes batch queries to avoid N+1 problems, and requires parameterized transactions. - Async & Serde Guidance: Directs correct mutex selection, spawn_blocking for CPU work, Box<RawValue> for passthrough JSON, and serde skip attributes. - Use Case: When adding a new Axum endpoint in windmill-api/src/, apply these patterns to destructure extractors, query the database with explicit columns, and return typed JSON results. ## Quick Start Ask the agent to write or modify Rust code in the Windmill backend directory and it will apply these conventions automatically.

Frequently Asked Questions about rust-backend

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I handle errors in Windmill Rust backend code?▼

Use the Error type from windmill_common::error and return Result<T, Error> or JsonResult<T>. Never panic in library code, and reserve .unwrap() only for compile-time guarantees.

Why should I avoid SELECT * in SQLx queries?▼

SELECT * breaks backwards compatibility when workers lag behind the API version and new columns are added. Always list columns explicitly in sqlx::query_as! macros so older workers keep functioning.

When should I use tokio::sync::Mutex vs std::sync::Mutex in Rust async code?▼

Prefer std::sync::Mutex or parking_lot::Mutex for general data protection. Only use tokio::sync::Mutex when you must hold the lock across .await points.

Should I use serde_json::Value or RawValue for JSON fields?▼

Use Box<serde_json::value::RawValue> when storing or passing JSON without inspecting it, since it avoids parsing overhead. Only use serde_json::Value when you need to inspect or modify the JSON content.

How do I avoid blocking the async runtime in Rust?▼

Wrap CPU-intensive work in tokio::task::spawn_blocking so it runs on a dedicated blocking thread pool. Avoid std::thread::sleep in async contexts and use bounded tokio::sync::mpsc channels for communication.