Skip to content

Instantly share code, notes, and snippets.

@IceWreck
Created March 1, 2026 22:31
Show Gist options
  • Select an option

  • Save IceWreck/d4c3f7facd3297de59019c466292f132 to your computer and use it in GitHub Desktop.

Select an option

Save IceWreck/d4c3f7facd3297de59019c466292f132 to your computer and use it in GitHub Desktop.
Rust Boilerplate
# Rust Boilerplate
### Init
In the empty git repo, init with `cargo init --edition 2024`. If the project also needs to have a lib then pass in `--lib`.
The repo tree should look something like this.
```
.
├── AGENTS.md
├── Cargo.lock
├── Cargo.toml
├── config
│ └── example.toml
├── Dockerfile
├── Makefile
├── README.md
└── src
├── bins
│ └── foobar
│ └── main.rs
├── config.rs
├── lib.rs
└── foo.rs
```
If the repo does not need any libs then you can exclude the bins folder and put the binaries directly in `src` .
### Agents MD
`AGENTS.md` file also symlink to `CLAUDE.md`.
```
# Agents Knowledge
## Code Conventions
- Use lowercase for log messages: `info!("starting xyz")`
- Log messages should not end with a period
- Log messages should start with lowercase (except proper nouns)
- Error messages should start with lowercase and not end with a period
- Error messages should use "failed to" / "unable to" phrasing
- Use early returns to reduce indentation
- Extract complex logic into functions
- Leverage data structures instead of deeply nested conditions
- Prefer clear variable and function names over comments
- Write self-explanatory code – readable without comments
- Explain "why" not "what" – comments clarify intent, don't restate code
- Avoid redundant comments – don't comment obvious things
- Use doc comments (`///`) for public items – document purpose, inputs, outputs
- Keep comments updated – outdated comments are worse than none
- Use inline comments sparingly – only when necessary
- Use `thiserror` for libraries (typed errors, public API)
- Use `anyhow` for applications (simple propagation, add context)
- Place integration tests in the top-level `tests/` directory
- Keep unit tests alongside the code in the same module files using the `#[cfg(test)]` module
## Preferred Libraries
- **clap** – CLI parsing
- **ratatui** + **crossterm** – Terminal UI
- **thiserror** – Library errors
- **anyhow** – Application errors
- **log** + **env_logger** – Logging
- **axum** – HTTP server
- **reqwest** – HTTP client
- **tokio** – Async runtime
- **serde** – Serialization
- **sqlx** – Database
## Development
```bash
cargo fmt # Format
cargo test # Test
cargo build # Build
cargo run --bin <your-bin-name>
```
```
### Makefile
```
.PHONY: *
SHELL := /bin/bash
IMAGE := code.abifog.com/packages/foobarbin:latest
build:
cargo build
release:
cargo build --release
podman-build:
podman build -t $(IMAGE) .
podman-push:
podman push $(IMAGE)
run:
cargo run
format:
cargo fmt
clean:
cargo clean
test:
cargo test
```
### Main
Just a hello world using the logger and clap for CLI creation.
It should load config file and then log it.
### Gitignore
```
# Environment files
.env
.env.*
# Build
build/
dist/
# IDE
.vscode/
.idea/
# OS
.DS_Store
# Other
/drafts
/config/config.toml
```
### Config.rs
```rust
use serde::{Deserialize, Serialize};
use std::path::Path;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("failed to read file: {0}")]
Io(#[from] std::io::Error),
#[error("failed to parse config: {0}")]
Parse(#[from] toml::de::Error),
#[error("config file not found: {0}")]
NotFound(String),
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Config {
pub foo: i32,
pub bar: String,
}
impl Config {
pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, ConfigError> {
let path = path.as_ref();
if !path.exists() {
return Err(ConfigError::NotFound(path.display().to_string()));
}
let content = std::fs::read_to_string(path)?;
let config: Config = toml::from_str(&content)?;
Ok(config)
}
}
```
### Dockerfile
```
# syntax=docker/dockerfile:1
FROM --platform=linux/amd64 docker.io/rust:1.85-alpine AS builder
WORKDIR /app
RUN apk add --no-cache musl-dev
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release --bin foobarbin
FROM --platform=linux/amd64 docker.io/alpine:latest
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/target/release/foobarbin /usr/local/bin/foobarbin
ENTRYPOINT ["foobarbin"]
CMD ["--help"]
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment