Tinker AI
Read reviews

Outcome

Tool shipped in two weekends; aider contributed ~40% of code; small Rust CLIs are an underrated AI fit

5 min read

Built a small CLI tool over two weekends using aider. The tool: a wrapper around kubectl that adds context-aware autocomplete and command history. About 1500 lines of Rust.

The interesting finding: Rust + aider works much better on small projects than on large ones. Below a certain code size, the friction I described in another case study (Rust + Cline on a larger service) mostly disappears. Here’s the breakdown.

The project

Specifications:

  • Rust 2021 edition
  • Clap for CLI parsing
  • Tokio for the small async surface (subprocess management)
  • Serde for config parsing
  • Aider with Claude 3.5 Sonnet

The codebase is small enough that the borrow checker rarely had to think hard. Most lifetimes are obvious; most ownership is straightforward.

What worked well

Clap setup and command structure. Aider scaffolded the CLI argument parser cleanly. Adding new subcommands took one prompt each.

Subprocess management. Wrapping kubectl calls, capturing output, parsing. Aider handled this competently — async patterns are simpler when the surface area is small.

Error handling. With anyhow for application errors, the chain of ? operators is straightforward. Aider produced reasonable error messages.

Config file parsing. Serde + TOML for the user config. Standard pattern, well-handled.

Tests. I asked aider to write integration tests using assert_cmd. The tests were structurally fine; I refined the assertions.

What didn’t work

The async patterns I deliberately added. I wanted to add async fetching of cluster info while parsing user input. The async-related code aider produced had issues with Send bounds. I rewrote that section by hand.

A custom serde deserializer. I wanted to handle a non-standard config format. Aider’s first attempt was wrong on the visitor pattern; the second attempt was right. Single-shot success rate was low for this niche pattern.

These two issues account for maybe 4 hours of friction in the project. Manageable.

The size matters

I’d estimate AI productivity at around 40% time savings on this project. That’s higher than my Cline-on-Rust-service experience (closer to 20%).

Why the difference? A few hypotheses:

Less context to load. A 1500-line project fits in the model’s effective attention easily. Aider’s repo map covers the whole thing without strain.

Fewer ownership chains. Small projects have shallower ownership relationships. The model can reason about them; the borrow checker validates; the cycle works.

Less library variety. Small CLIs use a few well-known libraries (clap, anyhow, serde, tokio). The model knows these well. Larger services use more libraries, some of which are obscure or domain-specific.

Faster verification. A 1500-line project compiles in seconds; tests run in seconds. The agent-loop’s feedback cycle is tight. On larger projects, the cycle is slower and the agent’s iteration speed drops.

A specific friction

One pattern that came up repeatedly: when I asked aider to add a new subcommand, it would sometimes “improve” existing subcommand definitions in subtle ways. The improvements weren’t wrong, but they introduced inconsistencies.

For example: existing subcommands had a specific style for their about strings. Aider would write new subcommands with a slightly different style. Or aider would refactor existing arg definitions while adding a new one.

Aider’s auto-commit behavior meant these drifts shipped before I noticed them. I started using --no-auto-commits and reviewing each commit manually for consistency.

This is a small-project-specific issue. On a small codebase, every change touches a non-trivial fraction of the code. Drift propagates fast. On a large codebase, the model’s changes are more localized.

What I’d recommend for similar projects

For developers considering AI tools on small Rust CLIs:

Default to aider over Cline or Cursor. The CLI form factor matches CLI tool development. Aider’s git-aware workflow fits well.

Use auto-commits cautiously. The drift issue I describe is real on small projects. Manual commits give you a chance to catch it.

Don’t try complex async on the small project. If your CLI is mostly synchronous with a small async surface, aider works. If you need lots of async, expect more friction.

Keep the codebase small. Resist the urge to over-engineer. Small CLIs are good projects for AI assistance specifically because they stay small.

Use clippy aggressively. clippy catches a category of mistakes the model occasionally makes. Run it often.

The cost

Aider API spend: $14.

Time invested: maybe 14 hours across two weekends.

Tool I shipped: usable, ~1500 lines of Rust, on GitHub.

For context, similar tools I’ve built without AI assistance took maybe 22-25 hours. The 30-40% savings is meaningful for a side project where time is the constraint.

What this taught me

Small projects in any language are a sweet spot for AI tools. The constraints that limit AI on large projects (context size, library variety, deep relationships) are minimal. The strengths of AI (fast typing, pattern matching, tirelessness) are still present.

For “weekend project” sized work, AI tools genuinely accelerate the process. The compounding investment in tooling and patterns pays off because you build more projects in the same time.

For larger projects, the picture gets more complex. The structural challenges of large codebases push back against AI productivity. Some categories of work suffer; some benefit; the net is more variable.

This isn’t a “small projects only” recommendation. It’s a “small projects are easy mode” observation. If you’re new to AI tooling and want to see what it can do, build a small CLI tool. The wins are clear; the friction is bounded; the experience is encouraging.

A note on Rust specifically

Rust has been the language I most often hear “AI tools don’t work for this.” That’s true for some Rust work — large services with deep type systems, complex async, lots of generics. It’s not true for all Rust work.

Small CLIs, simple servers, contained applications — Rust here is fine with AI tooling. The borrow checker isn’t fighting the model because the ownership patterns are simple. The agent loop closes because the project compiles fast.

If you’ve been avoiding Rust + AI based on hearing it doesn’t work, try a small project. Your experience may surprise you. The “Rust is hard for AI” narrative is more nuanced than the general framing suggests.