Download Beam

How to Use Claude Code for Rust Development: The Complete Workflow

February 2026 • 12 min read

Rust developers live in the terminal. cargo build, cargo test, cargo clippy, cargo fmt, cargo doc — the entire development lifecycle is CLI-first. There is no "Run" button, no integrated build system hiding behind a GUI. Every Rust developer already has a terminal workflow. The question is whether that workflow is organized or chaotic.

Claude Code understands Rust at a deep level. It knows the ownership model, lifetimes, trait bounds, error handling patterns, and the nuances of unsafe. It can explain why the borrow checker is rejecting your code and offer a fix that is idiomatic, not just correct. Combined with Beam for workspace organization, you get the ideal Rust development stack: an AI pair programmer that speaks Rust fluently, inside a terminal organizer built for multi-session workflows.

This guide walks through the complete workflow — from project scaffolding to performance profiling — showing how Claude Code and Beam work together for Rust development.

Beam — Rust Workspace Claude Code cargo watch cargo test $ claude > Implement Display and FromStr for AppError I'll implement Display using thiserror's derive macro and add FromStr with a custom parse error type... + impl Display for AppError { + fn fmt(&self, f: &mut + Formatter) -> fmt::Result // Rust src/error.rs $ cargo watch -x check Compiling myapp v0.1.0 Compiling myapp-core v0.1.0 Checking myapp-cli v0.1.0 Finished `dev` in 1.42s [Waiting for changes...] 0 errors, 0 warnings all checks passing Workspace 1 3 tabs • 2 panes

Setting Up Your Rust Workspace in Beam

A well-organized workspace is the foundation of a productive Rust workflow. Beam lets you create a dedicated Rust development environment where every terminal has a purpose and nothing gets lost.

The ideal Rust workspace layout:

For maximum productivity, use Beam's split panes. Press ⌘⌥⌃T to split your first tab horizontally: Claude Code on the left, compiler output on the right. This gives you an instant feedback loop — ask Claude Code to make a change, and watch the compiler validate it in real time.

Pro Tip: Save Your Rust Layout

Once you have your workspace configured with the right tabs and splits, press ⌘S to save it as a layout. Name it something like "Rust Dev." The next time you start a Rust project, restore the layout and you are instantly in your ideal environment — no setup required.

For larger projects, create multiple workspaces. One workspace per crate keeps things clean:

Workspace 1: "Core Library"

Workspace 2: "CLI Application"

Switch between workspaces with ⌘⌥←→. Each workspace maintains its own shell state, so your cargo watch keeps running when you switch contexts.

Scaffolding Rust Projects with Claude Code

Starting a new Rust project involves more than cargo new. You need the right dependencies, feature flags, project structure, and boilerplate. Claude Code handles all of this in a single prompt.

Binary Projects with Argument Parsing

Tell Claude Code what your CLI tool should do, and it generates the complete scaffold:

> Create a new Rust CLI tool called "logparse" that reads log files,
  filters by log level, and outputs JSON. Use clap for arg parsing,
  serde for JSON, and anyhow for errors. Set up the project structure
  with src/main.rs, src/lib.rs, src/parser.rs, and src/output.rs.

Claude Code will generate the Cargo.toml with pinned dependency versions, set up the clap derive-based argument parser, create the module structure with proper mod declarations, and include skeleton implementations for each module. It understands that a well-structured Rust binary separates the CLI interface from the library logic.

Library Crates with Public API Design

Library design in Rust requires careful thought about what is public and what stays private. Claude Code can scaffold a library with a clean API surface:

> Create a Rust library crate for a rate limiter. Public API should
  expose RateLimiter::new(max_requests, window_duration), .check(),
  and .reset(). Use a token bucket algorithm internally. Include
  builder pattern for configuration.

Claude Code will create the public structs and methods in lib.rs, keep implementation details in private submodules, add doc comments with examples on every public item, and set up #[cfg(test)] module skeletons for each file.

Workspace Projects with Multiple Crates

Cargo workspaces are the standard for Rust monorepos. Claude Code understands the workspace Cargo.toml format and inter-crate dependencies:

> Set up a Cargo workspace with three crates: myapp-core (library),
  myapp-server (binary, depends on core), and myapp-cli (binary,
  depends on core). Share common dependencies at workspace level.
  Enable LTO for release builds.

It will generate the root Cargo.toml with [workspace] members and shared [workspace.dependencies], each crate's Cargo.toml referencing workspace dependencies with dep.workspace = true, and a [profile.release] section with lto = true, codegen-units = 1, and strip = true for optimized binaries.

Cargo.toml Expertise

Claude Code knows the Cargo.toml specification deeply. Ask it to add feature flags, conditional compilation targets, or optional dependencies, and it generates correct, idiomatic configuration:

> Add an optional "tls" feature to my library that enables rustls
  support. When enabled, expose an additional connect_tls() method.
  Default features should include "tls".

Why Scaffolding with Claude Code Matters

Rust projects have more upfront structure than most languages. Module declarations, pub visibility, feature gates, and Cargo.toml configuration all need to be correct before you write a single line of business logic. Claude Code eliminates the boilerplate phase entirely, letting you jump straight into the problem you are actually trying to solve.

Rust-Specific Claude Code Workflows

Rust has a unique set of concepts that trip up developers at every experience level. Claude Code understands them all, and more importantly, it can explain why the compiler is complaining and offer idiomatic solutions.

Ownership and Borrowing

The borrow checker is Rust's defining feature and its steepest learning curve. When you hit a lifetime error, paste the compiler output into Claude Code:

> Fix this error:
  error[E0597]: `data` does not live long enough
  --> src/main.rs:12:22
     |
  12 |     let reference = &data;
     |                      ^^^^ borrowed value does not live long enough
  13 | }
     | - `data` dropped here while still borrowed

Claude Code does not just fix the code. It explains the ownership problem: what owns the data, what borrows it, and why the lifetimes do not align. Then it offers the right solution, whether that is restructuring the code, using Arc for shared ownership, cloning where appropriate, or adjusting lifetime annotations.

Common ownership scenarios Claude Code handles well:

Trait Implementations

Rust traits are pervasive. Almost every struct needs Debug, most need Display, and many need From/Into conversions. Instead of writing these by hand, ask Claude Code:

> Implement Display, Debug, From<io::Error>, From<serde_json::Error>,
  and Into<StatusCode> for my AppError enum. Also implement the Error
  trait properly.

Claude Code generates all the trait implementations with correct match arms, proper formatting, and idiomatic Rust style. It knows when to use #[derive(Debug)] versus a manual implementation, when Display should delegate to inner types, and how to chain From implementations for ergonomic error conversion with the ? operator.

Error Handling Patterns

Rust's error handling ecosystem has converged on two crates: thiserror for libraries and anyhow for applications. Claude Code knows which to use and when:

> Create an error type for my HTTP client library using thiserror.
  It should cover connection errors, timeout errors, invalid URL,
  HTTP status errors (with the status code), and deserialization
  errors. Include From impls for reqwest::Error and serde_json::Error.

For application code, Claude Code will use anyhow for quick, flexible error handling with context:

> Convert this function to use anyhow. Add .context() calls
  with meaningful error messages at each failure point.

The result is error handling that gives you clear error chains when something fails, without the verbosity of manually writing error types for application-level code.

Async Rust

Async Rust is powerful but notoriously complex. Pin, Future, Stream, Send + Sync bounds, and the distinction between tokio and async-std create a steep learning curve. Claude Code navigates this confidently:

> Create an async HTTP server using axum with three routes:
  GET /health, POST /data that accepts JSON and stores it,
  and GET /data/:id that retrieves it. Use tokio with multi-
  threaded runtime. Include graceful shutdown on SIGTERM.

Claude Code handles the common async pain points:

Unsafe Code Review

Sometimes unsafe is necessary. When it is, Claude Code can audit it and suggest safe alternatives:

> Audit this unsafe block. Is it sound? Can it be replaced with
  safe code?

  unsafe {
      let ptr = data.as_ptr();
      let slice = std::slice::from_raw_parts(ptr, data.len());
      process(slice);
  }

Claude Code will analyze whether the invariants required by from_raw_parts are maintained (valid pointer, correct length, proper alignment, no aliasing), and almost always suggest a safe alternative that performs identically. In this case, it would point out that the unsafe block is entirely unnecessary since data is already a slice.

Macro Generation

Rust macros — both declarative (macro_rules!) and procedural (derive macros) — are powerful but have notoriously difficult syntax. Claude Code excels here because macro patterns are repetitive and well-defined:

> Create a declarative macro called impl_from_str that takes a
  struct name and a list of field:type pairs, and generates a
  FromStr implementation that parses a comma-separated string
  into the struct.

Claude Code generates the macro with proper hygiene, clear token tree patterns, and helpful compile error messages using compile_error!. For derive macros, it can generate the full proc-macro crate structure with syn and quote.

Building CLI Tools in Rust

Rust is the dominant language for modern CLI tools. ripgrep, bat, fd, exa, zoxide, delta, hyperfine — the tools developers love most are written in Rust. Claude Code can help you build production-quality CLI tools with the same patterns.

The CLI Tool Stack

Tell Claude Code what your tool does, and it assembles the right crates:

Example: Building a Log Analyzer

Here is a real workflow using Claude Code and Beam for building a CLI tool:

Step 1: In your Claude Code pane, scaffold the project:

> Create a CLI tool called "loggrep" that searches structured
  JSON log files. It should support filtering by log level,
  time range, and regex pattern matching on message fields.
  Output as formatted text or JSON. Use clap, serde, regex,
  chrono, and colored.

Step 2: In your cargo watch pane, start the watcher:

$ cargo watch -x check -x clippy

Step 3: Iterate with Claude Code. Ask it to add features one at a time:

> Add a --follow flag that watches the file for new lines,
  like tail -f. Use notify for file watching.
> Add progress bar using indicatif when processing large files.
  Show bytes processed and estimated time remaining.
> Add shell completions generation. clap_complete for bash,
  zsh, and fish. Add a "completions" subcommand.

Each time Claude Code modifies a file, you see the compiler output in your other pane immediately. No context switching, no running commands manually. The feedback loop is instantaneous.

Beam Advantage: Split-Pane Feedback Loop

This is where Beam's split panes shine for Rust development. The Rust compiler is famously strict — and famously helpful. When Claude Code makes a change, the compiler catches issues within seconds in your adjacent pane. You can copy the error back to Claude Code and iterate without leaving your workspace. No tab switching, no lost context.

Testing in Rust with Claude Code

Rust has testing built into the language and toolchain. No test runner framework to install, no configuration files to maintain. Claude Code leverages this to generate comprehensive tests with minimal prompting.

Unit Tests

Rust convention places unit tests in a #[cfg(test)] module at the bottom of each file. Claude Code follows this convention automatically:

> Write unit tests for the parse_log_entry function. Cover valid
  JSON entries, malformed JSON, missing required fields, edge
  cases for timestamp parsing, and unicode in message fields.

Claude Code generates the mod tests block with #[test] functions, uses descriptive test names like test_parse_valid_entry_with_all_fields, includes both success and failure cases, and uses assert_eq! with meaningful messages.

Integration Tests

Integration tests live in the /tests directory and test your crate's public API. Claude Code knows the distinction:

> Create integration tests for the loggrep library. Test the
  full pipeline: read file, apply filters, produce output.
  Use tempfile for test fixtures.

It will create files in tests/ that import your crate as an external dependency, set up test fixtures with tempfile::NamedTempFile, and test the full workflow from input to output.

Doc Tests

Rust's doc tests are unique — code examples in documentation are compiled and run as tests. Claude Code writes doc examples that serve dual purpose: they document the API and verify it works:

> Add documentation with examples to all public functions in
  the rate_limiter module. Every example should be a complete,
  runnable doc test.

Property-Based Testing

For functions with complex invariants, Claude Code can set up property-based tests with proptest:

> Add property-based tests for the serialization module. Verify
  that for any valid Config value, serialize then deserialize
  produces the original value (roundtrip property).

Claude Code generates the proptest! macro invocations, custom Arbitrary implementations for your types, and targeted strategies that generate meaningful test inputs rather than purely random data.

Organizing Test Output in Beam

Dedicate a full tab to cargo test. Use the --nocapture flag to see println! output from tests, and --test-threads=1 when debugging test interactions. Beam keeps this output visible and scrollable while you work with Claude Code in another pane.

For test-driven development, run:

$ cargo watch -x "test -- --nocapture"

Every time Claude Code saves a file, the tests re-run automatically in your dedicated test tab.

The Cargo Watch Workflow

cargo-watch is the secret weapon for Rust's compile-check-test cycle. It watches your source files and re-runs commands on every change. Combined with Beam's split panes, it creates a development experience that rivals any IDE.

Setting It Up

Install cargo-watch if you have not already:

$ cargo install cargo-watch

Then in your dedicated Beam pane, run:

$ cargo watch -x check -x test -x run

This command chains three operations: first cargo check (fast type checking), then cargo test (if check passes), then cargo run (if tests pass). The chain short-circuits on failure, so you get the fastest possible feedback.

The Split-Pane Setup

The ideal layout in Beam:

When Claude Code modifies a Rust file, cargo-watch detects the change within a second. You see either green "Finished" messages or compiler errors. If there are errors, you can paste them directly back to Claude Code:

> I'm getting this error from cargo check:

  error[E0382]: borrow of moved value: `config`
  --> src/main.rs:45:20
     |
  42 |     let server = Server::new(config);
     |                              ------ value moved here
  45 |     println!("{}", config.port);
     |                    ^^^^^^^^^^^ value borrowed here after move

Claude Code will explain that Server::new took ownership of config, and suggest either passing a reference (&config), cloning the value, or restructuring the code to access config.port before the move.

Advanced Cargo Watch Configurations

For different stages of development, adjust the cargo watch command:

Managing Rust Workspaces

As Rust projects grow, they naturally split into multiple crates within a Cargo workspace. This is where Beam's workspace-per-crate organization becomes essential.

One Beam Workspace Per Crate

For a Cargo workspace with three crates (core, server, cli), create three Beam workspaces:

Beam Workspace "core":

Beam Workspace "server":

Beam Workspace "cli":

Shared Dependencies and Feature Flags

Claude Code understands Cargo workspace dependency management. Ask it to refactor dependencies to the workspace level:

> Move all shared dependencies (serde, tokio, tracing) to
  workspace-level dependencies. Update each crate's Cargo.toml
  to use dep.workspace = true syntax.

Or manage feature flags across crates:

> Add a "metrics" feature to the core crate that adds prometheus
  metrics to all public functions. The server crate should enable
  this feature by default, but the CLI crate should not.

Claude Code Context Per Crate

Claude Code uses memory files to maintain project context. For a multi-crate workspace, you can have a memory file at the workspace root with architectural decisions and one per crate with crate-specific context. Claude Code reads these automatically and understands the relationships between crates.

This means when you are working on the server crate and you ask Claude Code to add a feature, it already knows the API surface of core and can generate code that uses it correctly.

Performance Profiling with Claude Code

Rust developers care deeply about performance. Claude Code can help you measure, analyze, and optimize your code.

Benchmarking with Criterion

Claude Code sets up criterion benchmarks with proper statistical methodology:

> Create benchmarks for the parse_log_entry function using
  criterion. Benchmark with small (100 byte), medium (1KB),
  and large (10KB) log entries. Include throughput measurement.

It generates the benches/ directory structure, the benchmark harness with criterion_group! and criterion_main! macros, and parameterized benchmarks that measure both latency and throughput.

Run the benchmarks in a dedicated Beam tab:

$ cargo bench

Criterion generates HTML reports with statistical analysis. Claude Code can then help you interpret the results and identify optimization opportunities.

Flamegraph Analysis

For runtime profiling, the cargo-flamegraph tool generates interactive SVG flamegraphs. Claude Code can help you set it up and interpret the results:

> Set up flamegraph profiling for the server binary. Add a
  /debug/profile endpoint that records 10 seconds of CPU
  activity and returns a flamegraph SVG.

After generating a flamegraph, describe what you see to Claude Code:

> The flamegraph shows 40% of time in serde_json::from_str
  and 25% in regex::Regex::find. How can I optimize these?

Claude Code will suggest targeted optimizations: using serde_json::from_slice instead of from_str to avoid a UTF-8 validation pass, compiling the regex once with lazy_static! or std::sync::OnceLock instead of per-call, or switching to simd-json for SIMD-accelerated parsing.

Compiler Optimizations

Claude Code knows the Rust compiler's optimization knobs:

> Optimize my release build for binary size. I want the smallest
  possible binary for distribution.

It will configure:

Or for maximum runtime performance:

> Optimize for speed. I need the fastest possible execution
  for this data processing pipeline.

Claude Code will set opt-level = 3, enable lto = "fat", set target-cpu = "native" in RUSTFLAGS, and suggest algorithmic improvements based on your code's hot paths.

Real-World Rust + Claude Code Patterns

Here are patterns that come up repeatedly in real Rust development, where Claude Code provides significant value:

Serde Customization

Almost every Rust project uses serde, and almost every project needs custom serialization at some point. Claude Code handles the full spectrum:

Tracing and Observability

The tracing ecosystem is the standard for structured logging in Rust. Claude Code sets up the full stack:

> Add structured logging using tracing. Set up tracing-subscriber
  with JSON output for production and pretty-printed for dev.
  Add spans to all public functions and instrument async methods.

Cross-Compilation

Claude Code knows Rust's cross-compilation targets and toolchain management:

> Set up cross-compilation for Linux x86_64 and ARM64 from macOS.
  Add a Makefile with targets for each platform. Use cross for
  Docker-based compilation.

Build Rust Projects Faster with Beam

The terminal is every Rust developer's IDE. Beam organizes it with workspaces, tabs, and split panes designed for multi-session workflows like Claude Code + cargo watch.

Download Beam for macOS

Summary

Rust development is inherently terminal-centric. Every tool in the Rust ecosystem — cargo, clippy, rustfmt, rustup, cargo-watch, cargo-bench — runs in the terminal. Claude Code operates in the same environment, understanding Rust at a deep enough level to handle ownership, lifetimes, traits, async patterns, macros, and performance optimization.

Beam ties it all together by organizing the parallel terminal sessions that Rust development demands:

If you are building in Rust and working in the terminal, this is the workflow to adopt. Claude Code for the intelligence. Beam for the organization. Cargo for everything else.