Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

This page describes the internal architecture of flk for contributors and curious users.

Overview

flk is a Rust CLI application that generates and modifies Nix flake configurations. It acts as a user-friendly layer on top of Nix, handling the complexity of flake syntax and structure.

┌─────────────────────────────────────────────────────────┐
│                     flk CLI                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │  Commands   │  │   Parsers   │  │  Generator  │     │
│  │ (clap CLI)  │  │ (nom-based) │  │ (templates) │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
└─────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────┐
│                    Nix Flake Files                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │  flake.nix  │  │ .flk/       │  │ flake.lock  │     │
│  │   (root)    │  │ profiles/   │  │  (inputs)   │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
└─────────────────────────────────────────────────────────┘

Crate Structure

  • Binary crate (src/main.rs): CLI entrypoint using clap. Parses arguments and dispatches to command handlers in src/commands/.

  • Library crate (src/lib.rs): Core functionality exposed as a library:

    • flk::flake - Flake generation, parsing, and interfaces
    • flk::utils - Backup management, visual output, helpers
  • Nix integration (src/nix/): Wrappers for invoking nix commands (search, evaluate, develop) and processing output.

Parser Design

Parsers in src/flake/parsers/ use the nom library to read and modify specific sections of Nix files:

  • Surgical editing: Instead of parsing entire Nix files, parsers target specific sections (packages, env vars, commands) and track byte positions for precise modifications.
  • Round-trip safety: Parse → modify struct → render back to Nix syntax, preserving comments and formatting outside the edited section.

Each parser returns a section struct containing:

  • Parsed entries (packages, variables, etc.)
  • Byte positions (section_start, section_end, list_end)
  • Indentation information for consistent formatting

Template System

Templates in templates/ are embedded at compile time via include_str!:

  • templates/flake.nix - Root flake template
  • templates/default.nix - Default profile loader
  • templates/pins.nix - Version pinning structure
  • templates/profiles/*.nix - Language-specific profiles (rust, python, node, go, generic)

The generator (src/flake/generator.rs) selects and instantiates these templates based on project type.

Data Layout

A flk-managed project has this structure:

project/
├── flake.nix           # Root flake (generated by flk init)
├── flake.lock          # Nix lock file (managed by Nix)
└── .flk/
    ├── default.nix     # Default profile selector
    ├── pins.nix        # Version pinning data
    ├── overlays.nix    # Package overlays
    ├── profiles/
    │   ├── default.nix # Default profile (symlink or import)
    │   ├── rust.nix    # Language-specific profile
    │   └── ...
    └── backups/        # Lockfile backups from flk update

Command Flow

  1. CLI parsing: clap in src/main.rs parses arguments
  2. Command dispatch: Each subcommand calls a run_* function in src/commands/
  3. File operations: Commands use parsers to read/modify .flk/ files
  4. Nix operations: Search, version lookup, and activation run through nix wrappers
  5. User feedback: Spinners and formatted output via src/utils/visual.rs

Key Interfaces

  • FlakeConfig: Complete flake configuration with profiles, packages, env vars
  • Profile: Single profile with packages, commands, environment variables
  • Package: Package entry with name and optional version pin
  • SourcesSection / OverlaysSection: Version pinning data structures