Build a Disk Usage Analyzer in Rust Like du and ncdu
du walks a tree and adds up file sizes. The interesting decisions are hard links counted once, symlinks left alone and how to keep going when a directory is unreadable.
Explore various tutorials from the learning catalog.
du walks a tree and adds up file sizes. The interesting decisions are hard links counted once, symlinks left alone and how to keep going when a directory is unreadable.
A fuzzy finder reads lines, filters them as you type and prints the one you pick. The pieces are raw mode input, a matching engine and a small redraw loop.
pulldown-cmark turns Markdown into a stream of events, and its HTML writer renders them. A small CLI adds file handling, options and a page template around it.
A jq clone needs three parts: a parser for a small path language, an evaluator over serde_json values and a printer. The core is about 150 lines.
Aya lets you write both the eBPF program and its loader in Rust. A small tracepoint program counts syscalls and a user space process reads the counters from a map.
Neovim talks to rust-analyzer through its built-in LSP client. A short config gives completion, diagnostics, formatting and Treesitter highlighting, and rustaceanvim adds Rust extras.
A dev container puts the toolchain, system libraries and services in a Docker image that the editor attaches to. A new contributor opens the folder and everything works.
A good Rust pipeline runs the same few checks in the same order every time. Format, clippy, tests, docs and a cache cover most projects in about forty lines of YAML.
pgvector adds a vector type and nearest-neighbor operators to Postgres. From Rust you store embeddings as arrays, index them with HNSW and query with an ORDER BY on distance.
napi-rs generates a Node-API addon from annotated Rust. Functions become JavaScript functions, async work runs on a thread pool, and TypeScript types come for free.
PyO3 turns Rust functions and structs into Python modules, and Maturin builds and publishes them as wheels. A hot loop moves to Rust and the rest of the program stays Python.
A good binding is two crates. The sys crate mirrors the C header exactly, and the safe crate hides the pointers behind types that cannot be misused.
To expose Rust to C, mark functions extern "C" with a stable name, build a staticlib or cdylib and let cbindgen write the header. The rules are about layout, ownership and panics.
Rust calls C through extern declarations that you write or generate. bindgen reads a header and produces them, leaving you to wrap the unsafe calls in a safe API.
The goal of unsafe code is to contain it. A safe wrapper has a small unsafe core, private fields that protect invariants and an API that cannot be misused from safe code.
A global allocator is a type implementing GlobalAlloc, registered with one attribute. Wrapping the system allocator with atomic counters gives you live memory numbers.
Microcontrollers have kilobytes, not megabytes. Most of the savings come from five profile settings, avoiding the formatting machinery and finding the large symbols with cargo-bloat.
Bevy organizes a game as data and functions. Entities are IDs, components are plain structs and systems are ordinary functions that query for the components they need.
Under systemd a daemon does not fork or write pid files. It stays in the foreground, tells systemd when it is ready and exits cleanly on SIGTERM.
Network tools read bytes off the wire and interpret headers. Rust makes the parsing safe with slices and explicit offsets, and crates handle the platform socket details.
cargo-dist generates a release workflow that builds your binary for every platform, packages it and publishes installers when you push a version tag.
A log analyzer is a streaming pipeline: read lines, parse with a regex, fold into counters and print the top entries. Iterators keep memory flat on gigabyte files.
OpenTelemetry gives traces, metrics and logs one vocabulary and one export path. In Rust you keep using tracing and add layers that ship to a collector.
Guessing at performance wastes time. Reproduce the slowness, record a flamegraph and fix the widest bar. This walks one endpoint from 40 ms to 6 ms.
A load test is only useful if it models real traffic and reports percentiles. oha gives a quick check, and k6 scripts realistic user flows with thresholds.
A presigned URL lets the browser upload straight to S3, so your service never touches the bytes. The server signs, the client uploads, and a confirmation step records the result.
A web request should not wait for email or image resizing. Move that work to a queue, run workers that retry on failure, and decide how durable the queue must be.
Wire Actix Web 4 to a SQLx 0.9 pool the right way: build the pool once outside the factory closure, share it as web::Data, map errors with ResponseError, and see the 8 versus 28 connection difference when it goes wrong.
Compiling Rust is easy to retarget, and linking is the hard part. Add the target, point Cargo at a linker, or let cross or zig supply a toolchain.
A Cargo subcommand is a binary named cargo-something. The interesting parts are the argument Cargo passes, reading the workspace with cargo_metadata and installing it.
A pool hands out reusable connections, caps how many exist and takes them back on drop. Building a small one explains the knobs on SQLx and deadpool.
A token bucket allows bursts up to a capacity and a steady refill rate. The whole algorithm is a timestamp and a float, and the async part is waiting for the next token.
A chat room is a one to many fan out. Tokio's broadcast channel gives each client its own receiver, and lagging clients are handled for you.
The core of every network service is an accept loop that spawns a task per connection. This walks through an echo server and a line protocol with Tokio, then adds limits.
A hang is usually one of four things: a blocked runtime thread, a lock held across an await, a future that never wakes or a channel nobody closes. Here is the order to check them.
An executor is a loop that polls tasks when their wakers fire. Build one with the standard library alone and Tokio stops looking like magic.
An async fn is a state machine behind the Future trait. Writing a future yourself, with poll and a waker, removes the mystery from await.
Most people stall in Rust at the same three places. This path orders the topics so each one rests on the last, and tells you what to skip until you need it.
PHP developers move from a request-per-process model to long lived services. This guide translates arrays, classes, exceptions and Composer into Rust and covers what changes at runtime.
Java developers know strong typing and tooling. This guide translates classes, interfaces, generics, exceptions and Maven into their Rust equivalents, and shows what changes without a JVM.
C++ developers know manual lifetimes. Rust turns the rules you follow by habit into compiler checks. This guide maps RAII, templates, move semantics and build tools across.
Go and Rust share a preference for plain code and explicit errors. This guide shows where they diverge: ownership, traits, generics and the way concurrency is checked.
TypeScript developers already think in types and async code. This guide maps each JavaScript habit to its Rust form and warns about the places where the mapping breaks.
Python developers already know most of what Rust asks for. This guide maps each Python habit to its Rust equivalent and names the three shifts that cause most of the early compiler errors.
Move a Python or Node service to Rust one route at a time: the strangler approach with a proxy, shared contracts, parity tests, data ownership and when to stop.
Change a type or signature and let rustc list every place that must change. A method for safe large refactors: make the change, follow errors, keep tests green at each step.
Implement undo and redo in Rust with the command pattern: commands as an enum, execute and undo methods, history stacks, merging, and a text editor example.
Event sourcing stores changes as an append-only list of events and derives state by folding them. A small Rust example: events enum, aggregate, command handling, store and replay.
Build a Grafana dashboard for a Rust service from Prometheus metrics: the RED panels, PromQL for rate, errors and p99, saturation panels, variables and alert rules.
Run a Rust service on Kubernetes properly: a Deployment with liveness and readiness probes, resource requests and limits, graceful shutdown with SIGTERM, and a rolling update strategy.
Build and deploy a Rust function to AWS Lambda with cargo-lambda: project template, lambda_runtime handler, ARM builds, deploy, invoke locally, cold starts and limits.
Deploy a Rust web service to Fly.io from scratch: Dockerfile, fly launch, fly.toml with health checks, secrets, a Postgres attachment, scaling and rollbacks.
Run untrusted plugins or user code from Rust inside WebAssembly with wasmtime: fuel for CPU limits, memory caps, no ambient file or network access, and host functions you choose.
Fuzz a Rust parser for security bugs: panics, hangs, huge allocations and unsafe memory errors. Set up targets with limits, run with sanitizers and triage crashes.
Implement the OAuth 2 authorization code flow with PKCE in Rust using the oauth2 crate: build the client, redirect, verify state, exchange the code and store tokens safely.
A reproducible build produces the same bytes from the same source anywhere. See what breaks it in Rust (paths, timestamps, toolchains), how to fix each, and how to verify a binary.
A guide to compiling Rust to WebAssembly: the targets, wasm-bindgen, calling between Rust and JavaScript, size, testing and when WebAssembly is worth it.
Debug Rust in VS Code with the CodeLLDB extension: install, a launch.json, breakpoints, conditional breakpoints, watch expressions, debugging tests and common problems.
A map of Rust debugging tools in the order to reach for them: compiler messages, dbg!, tests, backtraces, tracing, a debugger and sanitizers, with when each one wins.
Find where a Rust service's memory goes: read RSS and allocator stats, profile allocations with dhat or heaptrack, tell a leak from growth, and fix the usual causes.
Profile guided optimization compiles twice: once to collect a profile from a real workload, once to optimize with it. Do it by hand or with cargo-pgo, and judge the gain.
A working guide to error handling in Rust: Result, the question mark, custom error types, anyhow and thiserror, and the line between a panic and an error.
Fuzz a Rust function with cargo-fuzz and libFuzzer: init, write a target, run, read crashes, minimize inputs, add a corpus and turn findings into regression tests.
A guide to unsafe Rust: what the keyword allows, the contract it creates, how to wrap it in a safe API, how to check it with Miri and where it is actually needed.
Boot a minimal Rust kernel in QEMU: a no_std crate, the bootloader crate, a disk image, a panic handler and writing text to the serial port in a few dozen lines.
A plan for writing an operating system kernel in Rust: the order of milestones from booting to a shell, which crates help, what to read and the traps at each stage.
Program an STM32 in Rust with probe-rs: pick the target, create a project from the cortex-m template, use embassy-stm32 or a PAC and HAL, flash, log and debug.
Blink an LED on a Raspberry Pi Pico in async Rust with Embassy: toolchain target, memory.x, probe-rs runner, the main task and a second task with a button.
Build a git hook manager in Rust: read a hooks config, install shims into .git/hooks, run commands on staged files in order, and report results with proper exit codes.
Build a todo list CLI in Rust with clap subcommands, serde JSON storage, stable ids, atomic and durable saves, and a file lock that stops concurrent runs from losing items. Every claim measured.
Build a Markdown link checker in Rust: extract links with pulldown-cmark, check them concurrently with reqwest and a semaphore, retry, report and set exit codes.
Build a fast file finder in Rust: parallel directory walking with the ignore crate, glob and regex filters, size and type predicates, and sorted deterministic output.
Build a grep clone in Rust from a naive version that panics on Latin-1 text to a streaming one that searches 72 MB in 77 ms with 2.5 MB of memory, handling binary files, exit codes and broken pipes.
Build a terminal user interface with Ratatui: init and restore, the draw loop, widgets and layout, handling key events and state, with a small counter and list app.
Test an Axum API against a real Postgres started by Testcontainers: one container per test binary, one migrated database per test, the leaks and version traps that bite, and measured timings for each isolation strategy.
Wire Axum 0.8 and SQLx 0.9 into a typed database layer: a pool in state, a db module of compile-time checked queries, one error type, a transaction, offline builds and tests on throwaway databases.
Build a chat room over WebSockets in Axum 0.8, using a Tokio broadcast channel to fan messages out, two tasks per socket, size limits and an integration test that drives real clients.
Shrink a Rust binary in steps: strip symbols, size optimization, LTO, panic abort, dependency pruning and cargo bloat to find what takes the space.
A guide to Cargo beyond cargo build: the manifest, dependency versions, features, workspaces, profiles, MSRV, publishing and the errors you will meet along the way.
A practical threat model for Rust code: what the compiler prevents, what it does not, and the checklist of supply chain, input handling, secrets, cryptography and deployment risks.
A guide to testing Rust code: unit tests beside the code, integration tests in tests, doc tests, property tests, snapshots, mocks, async tests and the commands to run them.
A guide to taking a Rust service from cargo build to production: release profile, CI, containers, configuration, secrets, health checks, observability and safe rollouts.
A guide to making Rust programs faster by measuring first: release builds, flamegraphs, allocation counts, benchmarks and the order to look at things.
rustup installs and switches Rust toolchains, targets and components. A guide to channels, overrides, rust-toolchain.toml, cross targets, offline use and clean upgrades.
How to structure a Rust codebase as it grows: modules, a lib and bin split, workspaces, layers and the boundaries that keep compile times and coupling in check.
A guide to SQLx: async queries without an ORM, compile-time checked SQL, pools, migrations, transactions and the choices around them.
A guide to embedded Rust from the first blinking LED to firmware structure: no_std, the HAL traits, runtimes, flashing, debugging and size.
Build a command line tool in Rust from the first clap derive to a release binary: arguments, config, output, exit codes, tests and distribution.
Build a small Axum 0.8 service from an empty crate to something you can deploy: a testable router, one error type, limits and timeouts, tracing, oneshot tests and graceful shutdown on SIGTERM.
A guide to async Rust and Tokio: futures, the runtime, spawning, blocking, channels and the mistakes that make a service stop answering.
A guide to choosing between generics, impl Trait, trait objects and enums in Rust, with one example solved four ways and the costs of each.
A fast route through the Rust language for developers who already code in another language, built around one small program that touches ownership, enums, traits and errors.
We send one email when a new post is published. No spam.