My Rust Development Setup on Garuda Linux with VS Code: A Developer's Journey

My Rust Development Setup on Garuda Linux with VS Code: A Developer's Journey
min read

My Rust Development Setup on Garuda Linux with VS Code: A Developer's Journey

You know that feeling when you finally get your development environment just right? After months of tweaking, testing, and honestly getting frustrated with slow compile times and memory-hungry language servers, I think I've cracked the code for the perfect Rust setup.

I've been building Rust projects for a while now – from my Discord bot library rustycord to puzzle solvers like sudoko and sudoko-tui, and even a hardware automation system for PhotoBooth. Through all these projects, I've learned what actually matters in a development setup and what's just noise.

Let me walk you through how I've configured VS Code on Garuda Linux to make Rust development feel effortless. This isn't just another "here's my dotfiles" post – this is the setup that's helped me ship real projects and actually enjoy the process.

Why I Chose Garuda Linux for Rust Development

Before diving into the VS Code magic, let me tell you why I fell in love with Garuda GNOME for my daily coding sessions:

The Garuda Experience

Performance That Actually Matters: Look, I'm not going to lie – Rust compilation can be slow. But Garuda's out-of-the-box optimizations, especially that Zen kernel, make a real difference. When you're waiting for cargo build to finish for the hundredth time today, every second counts.

AUR is a Game Changer: Coming from Ubuntu, having access to the AUR feels like having superpowers. Need the latest version of a tool? It's probably in AUR. Want to try some experimental Rust tooling? AUR has got you covered. No more adding sketchy PPAs or compiling from source at 2 AM.

It Just Worksβ„’: I know this sounds clichΓ©, but after distro-hopping for years, I appreciate something that doesn't break when I update it. Garuda strikes that perfect balance – powerful enough for serious development, stable enough that I'm not troubleshooting driver issues when I should be writing code.

Beautiful and Functional: Let's be honest – we spend 8+ hours a day looking at our screens. Garuda's aesthetic doesn't hurt, and the GNOME workflow with their customizations actually makes me more productive.

Installing Rust: Don't Use Your Package Manager

Here's my first piece of advice: ignore your package manager for Rust installation. I know it's tempting to just run sudo pacman -S rust, but trust me on this one:

bash
# Install rustup (the official Rust toolchain installer)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Add cargo to your PATH (add this to your ~/.zshrc since we're on Garuda)
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

# Install the latest stable toolchain
rustup install stable
rustup default stable

# Add the essential components (you'll thank me later)
rustup component add clippy rustfmt rust-src rust-analyzer

Why rustup over pacman? Simple: you get better control over versions, easier switching between toolchains for testing, and you're always up-to-date with the latest Rust releases. When you're working on multiple projects that might need different Rust versions, you'll appreciate this flexibility.

VS Code Configuration: The Heart of My Setup

Now, let's get to the meat of this post – my VS Code configuration. I use a dedicated profile called "Hrithik Rust" for all my Rust development, which keeps my setup clean and isolated.

Essential Extensions

Here are the extensions that make my Rust development experience smooth:

json
{
  "rust-lang.rust-analyzer": "The language server that makes everything possible",
  "tamasfe.even-better-toml": "Because Cargo.toml deserves syntax highlighting",
  "dustypomerleau.rust-syntax": "Enhanced Rust syntax highlighting",
  "tauri-apps.tauri-vscode": "Essential for my Tauri projects like SpendLite",
  "github.copilot": "AI pair programming that actually understands Rust",
  "github.copilot-chat": "When I need to brainstorm Rust solutions",
  "eamodio.gitlens": "Git integration that saves my sanity",
  "shd101wyy.markdown-preview-enhanced": "For documentation and README files"
}

My VS Code Settings Configuration

Here's the configuration that makes everything work smoothly together:

json
{
    "editor.fontFamily": "cascadia code nf",
    "editor.fontSize": 13,
    "editor.fontWeight": "600",
    "workbench.colorTheme": "Bluloco Dark Italic",
    "workbench.iconTheme": "bearded-icons",
    "workbench.productIconTheme": "fluent-icons",
    
    // Auto-save is crucial for rust-analyzer feedback
    "files.autoSave": "afterDelay",
    "editor.formatOnSave": true,
    
    // Rust-specific settings that improve performance
    "rust-analyzer.cargo.loadOutDirsFromCheck": false,
    "rust-analyzer.procMacro.enable": false,
    "rust-analyzer.memoryUsage": "low",
    
    // Exclude directories to improve performance
    "rust-analyzer.files.excludeDirs": [
        "node_modules",
        "target",
        "dist",
        "build"
    ],
    "files.watcherExclude": {
        "**/node_modules/**": true,
        "**/target/**": true
    },
    "search.exclude": {
        "**/node_modules": true,
        "**/target": true
    },
    
    // GitHub Copilot configuration
    "github.copilot.enable": {
        "*": true,
        "rust": true
    },
    
    // Terminal and debugging
    "debug.allowBreakpointsEverywhere": true,
    "terminal.integrated.fontWeightBold": "bold"
}

Why These Settings Matter

Let me explain some of the key choices:

Font Choice: Cascadia Code NF with weight 600 gives me excellent readability for Rust's sometimes verbose syntax. The Nerd Font variant includes icons that various extensions use.

Performance Optimizations: Those rust-analyzer settings might seem limiting, but they're crucial when working on larger projects. I learned this the hard way when rust-analyzer was consuming 8GB+ RAM on my PhotoBooth project.

File Exclusions: Excluding target/ directories from search and file watching is essential. Rust's compilation artifacts can be massive, and you don't want your editor scanning through them.

The Development Workflow That Works

Project Setup

When I start a new Rust project, here's my typical setup:

bash
# Create new project
cargo new my-awesome-project
cd my-awesome-project

# Initialize git (if not already done)
git init

# Create a .gitignore if cargo didn't
echo "/target" > .gitignore
echo "Cargo.lock" >> .gitignore  # Only for libraries

# Open in VS Code with the Rust profile
code --profile "Hrithik Rust" .

Essential Cargo.toml Additions

I almost always add these to my projects:

toml
[profile.dev]
# Faster compilation for development
opt-level = 1

[profile.release]
# Maximum optimization for release builds
opt-level = 3
lto = true
codegen-units = 1
panic = "abort"

# Development dependencies I commonly use
[dev-dependencies]
tokio-test = "0.4"  # For async testing
criterion = "0.5"   # For benchmarking

Daily Development Commands

These are the commands I use most frequently:

bash
# Check code without building
cargo check

# Run with automatic recompilation
cargo watch -x run

# Run tests in watch mode
cargo watch -x test

# Format code (configured to run on save)
cargo fmt

# Lint code
cargo clippy

# Build for release
cargo build --release

# Generate documentation
cargo doc --open

Debugging Configuration

Here's my launch.json configuration for debugging Rust applications:

json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug executable",
            "cargo": {
                "args": [
                    "build",
                    "--bin=${workspaceFolderBasename}",
                    "--package=${workspaceFolderBasename}"
                ],
                "filter": {
                    "name": "${workspaceFolderBasename}",
                    "kind": "bin"
                }
            },
            "args": [],
            "cwd": "${workspaceFolder}"
        },
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug unit tests",
            "cargo": {
                "args": [
                    "test",
                    "--no-run",
                    "--bin=${workspaceFolderBasename}",
                    "--package=${workspaceFolderBasename}"
                ],
                "filter": {
                    "name": "${workspaceFolderBasename}",
                    "kind": "bin"
                }
            },
            "args": [],
            "cwd": "${workspaceFolder}"
        }
    ]
}

Real-World Project Examples

Let me share how this setup has helped me with my actual projects:

Building rustycord (Discord Bot Library)

For rustycord, the async nature and complex type systems really benefited from rust-analyzer's excellent type inference. The auto-completion for async/await patterns and the instant error checking saved me countless hours.

rust
// Example from rustycord - VS Code makes this a breeze
impl EventHandler for MyBot {
    async fn message(&self, ctx: Context, msg: Message) -> Result<()> {
        if msg.content == "!ping" {
            msg.channel_id.say(&ctx.http, "Pong!").await?;
        }
        Ok(())
    }
}

Sudoko Solver Performance Optimization

When working on my sudoko crates, the integrated benchmarking and profiling features helped me optimize the solving algorithms. The debugging setup made it easy to step through recursive solving functions.

PhotoBooth Hardware Integration

The PhotoBooth project involves a lot of FFI (Foreign Function Interface) for camera control. VS Code's debugging capabilities were crucial for working with unsafe code blocks and C library integrations.

Productivity Tips and Tricks

1. Workspace-Specific Settings

I use .vscode/settings.json in each project to override global settings:

json
{
    "rust-analyzer.cargo.features": ["feature1", "feature2"],
    "rust-analyzer.cargo.target": "x86_64-unknown-linux-gnu"
}

2. Code Snippets

I've created custom snippets for common Rust patterns:

json
{
    "tokio main": {
        "prefix": "tokio-main",
        "body": [
            "#[tokio::main]",
            "async fn main() -> Result<(), Box<dyn std::error::Error>> {",
            "    ${1:// Your code here}",
            "    Ok(())",
            "}"
        ]
    }
}

3. Tasks Configuration

My tasks.json for common Rust operations:

json
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cargo",
            "command": "check",
            "group": "build",
            "label": "rust: cargo check"
        },
        {
            "type": "cargo",
            "command": "test",
            "group": "test",
            "label": "rust: cargo test"
        },
        {
            "type": "cargo",
            "command": "run",
            "group": "build",
            "label": "rust: cargo run"
        }
    ]
}

Performance Considerations

System Resources

Rust compilation can be resource-intensive. Here's how I manage it:

RAM Usage: With my current settings, rust-analyzer typically uses 2-4GB RAM for large projects. The memoryUsage: "low" setting helps keep it manageable.

CPU Usage: Compilation benefits from Garuda's performance optimizations. I've set up cargo to use multiple cores:

bash
# Add to ~/.cargo/config.toml
[build]
jobs = 8  # Adjust based on your CPU cores

SSD Benefits: Rust's incremental compilation really benefits from fast storage. If you're on Garuda with an SSD, you'll notice significantly faster rebuild times.

Troubleshooting Common Issues

rust-analyzer Not Working

Sometimes rust-analyzer gets confused. Here's my troubleshooting checklist:

bash
# Restart rust-analyzer
# VS Code Command Palette: "rust-analyzer: Restart server"

# Clear cargo cache
cargo clean

# Update rust-analyzer
rustup component add rust-analyzer --force

# Check rust-analyzer logs in VS Code Output panel

High Memory Usage

If rust-analyzer is eating too much RAM:

json
{
    "rust-analyzer.memory.useLimit": 4096,  // 4GB limit
    "rust-analyzer.cargo.loadOutDirsFromCheck": false,
    "rust-analyzer.procMacro.enable": false
}

Slow Compilation

For faster development iterations:

toml
# In Cargo.toml
[profile.dev]
opt-level = 1
debug = true
incremental = true

Advanced Features I Actually Use

1. Inlay Hints

These show type information inline – incredibly helpful for complex generic code:

json
{
    "rust-analyzer.inlayHints.enable": true,
    "rust-analyzer.inlayHints.parameterHints": true,
    "rust-analyzer.inlayHints.typeHints": true
}

2. Code Actions

rust-analyzer's code actions (the lightbulb icon) are fantastic:

  • Auto-import missing items
  • Fill in missing match arms
  • Generate boilerplate code
  • Extract functions/variables

  • 3. Semantic Highlighting

    This goes beyond syntax highlighting to show semantic meaning:

    json
    {
        "editor.semanticHighlighting.enabled": true,
        "rust-analyzer.highlighting.strings": true
    }

    Integration with GitHub Copilot

    GitHub Copilot has been a game-changer for my Rust development. Here's how I've configured it:

    json
    {
        "github.copilot.enable": {
            "rust": true
        },
        "github.copilot.nextEditSuggestions.enabled": true
    }

    Copilot is particularly good at:

  • Generating boilerplate async code
  • Suggesting error handling patterns
  • Completing complex trait implementations
  • Writing test cases

  • The Results: Productivity Gains

    Since setting up this environment, I've noticed significant improvements:

    Faster Development: The combination of auto-save, format-on-save, and instant error checking means I catch issues immediately rather than during compilation.

    Better Code Quality: Clippy integration and GitHub Copilot suggestions have improved my Rust idiom usage.

    Reduced Context Switching: Everything I need is in one place – debugging, terminal, git, and documentation.

    Project Consistency: Using workspace settings ensures all my projects follow the same patterns.

    What's Next?

    I'm constantly evolving this setup. Some things I'm experimenting with:

    WebAssembly Development: Adding wasm-pack integration for projects that compile to WASM.

    Cross-compilation: Setting up targets for different platforms directly in VS Code.

    Custom Extensions: I'm considering writing a VS Code extension specifically for some of my common Rust workflows.

    Final Thoughts

    This setup has been refined through building real projects – from Discord bots to TUI applications to hardware control systems. It's not about having the most extensions or the most complex configuration; it's about having a setup that gets out of your way and lets you focus on solving problems with Rust.

    The beauty of this configuration is that it scales well. Whether I'm prototyping a small CLI tool or working on a complex async system like rustycord, the same setup serves me well.

    If you're starting your Rust journey or looking to improve your development experience, I'd recommend starting with the basics (rust-analyzer + decent settings) and gradually adding features as you identify pain points in your workflow.

    Remember, the best development environment is the one that makes you want to code more. For me, this VS Code setup on Garuda Linux does exactly that – it makes Rust development not just productive, but genuinely enjoyable.

    ---

    Want to see this setup in action? Check out my projects on GitHub or visit my website at iamdhakrey.dev to see what I'm building with this setup.

    Quick Setup Checklist

    If you want to replicate this setup quickly:

    1. βœ… Install Garuda Linux (GNOME edition recommended) 2. βœ… Install Rust via rustup 3. βœ… Install VS Code 4. βœ… Create a dedicated Rust profile in VS Code 5. βœ… Install the essential extensions listed above 6. βœ… Copy the settings configuration 7. βœ… Set up debugging configuration 8. βœ… Create your first Rust project and start coding!

    Happy coding, and may your compile times be short and your memory safety be guaranteed! πŸ¦€

    β€’ Made With Love on