# Main Components and Packages in the Dive Repository: Architecture Guide

> Understand the main components of the Dive repository. Explore its CLI bootstrap, core analysis engine, and interactive UI architecture for efficient image analysis.

- Repository: [Alex Goodman/dive](https://github.com/wagoodman/dive)
- Tags: architecture
- Published: 2026-03-07

---

**Dive is organized into three functional tiers: a CLI bootstrap layer in `cmd/dive`, a core analysis engine within the `dive` package (handling image resolution and file-tree diffing), and an interactive terminal UI built on gocui, supported by shared utilities in `internal/*`.**

Dive is an open-source tool written in Go for exploring Docker and OCI container images. Understanding the main components and packages in the Dive repository is essential for developers who want to contribute to the project or integrate its analysis capabilities into their own workflows. The codebase follows a clean separation between command-line plumbing, image analysis logic, and terminal user interface rendering.

## High-Level Architecture

The repository follows a three-tier architecture that cleanly separates concerns between user interaction, data processing, and system infrastructure.

The **CLI entry point** ([`cmd/dive/main.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/main.go)) handles flag parsing and application bootstrap using the **clio** framework. The **core analysis engine** (rooted in the `dive` directory) resolves container images from various sources, extracts filesystem layers, and computes differential changes. Finally, the **user interface layer** (`cmd/dive/cli/internal/ui/v1`) renders the interactive terminal experience using the **gocui** library.

## Core Package Breakdown

### CLI Entry Point and Command Handling (`cmd/dive`)

The application lifecycle begins in [`cmd/dive/main.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/main.go), which constructs a `cli.Application` via the **clio** library. This package registers top-level commands and delegates execution to the CLI implementation found in [`cmd/dive/cli/cli.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/cli.go).

Configuration structures defined in `cmd/dive/cli/internal/options/`—such as [`analysis.go`](https://github.com/wagoodman/dive/blob/main/analysis.go), [`export.go`](https://github.com/wagoodman/dive/blob/main/export.go), and [`ci.go`](https://github.com/wagoodman/dive/blob/main/ci.go)—map command-line flags and configuration file settings onto the core engine. These option structures determine whether Dive runs in interactive UI mode, exports JSON, or executes CI validation rules.

### Image Resolution and Layer Handling (`dive/image`)

The `dive/image` package defines the abstract `Resolver` interface in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go). This interface abstracts away the specifics of how container images are fetched and parsed.

Concrete implementations include:
- **Docker Engine resolver**: [`dive/image/docker/engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/engine_resolver.go) for live Docker daemon access
- **Docker Archive resolver**: [`dive/image/docker/archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/archive_resolver.go) for tar archives
- **Podman resolver**: [`dive/image/podman/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/podman/resolver.go) for Podman engine support

The factory function `dive.GetImageResolver` (in [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go)) determines the appropriate resolver based on the detected `ImageSource`. Each resolver returns `image.Layer` objects (defined in [`dive/image/layer.go`](https://github.com/wagoodman/dive/blob/main/dive/image/layer.go)) that encapsulate layer metadata including size, ID, command history, and a pointer to their filesystem representation.

### File-Tree Analysis Engine (`dive/filetree`)

At the heart of Dive's analysis capabilities is the `dive/filetree` package. The `FileTree` type (in [`dive/filetree/file_tree.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/file_tree.go)) provides an in-memory representation of a filesystem snapshot, with `FileNode` structs representing individual files and directories.

This package handles:
- **Diffing logic**: [`filetree/diff.go`](https://github.com/wagoodman/dive/blob/main/filetree/diff.go) implements `CompareAndMark` to annotate files as added, removed, or modified across successive layers
- **Efficiency calculations**: [`filetree/efficiency.go`](https://github.com/wagoodman/dive/blob/main/filetree/efficiency.go) computes wasted space metrics used in the CI validation mode
- **Rendering utilities**: Methods like `String(true)` generate ASCII tree representations for the terminal UI

### Terminal User Interface (`cmd/dive/cli/internal/ui/v1`)

The interactive experience is implemented in [`cmd/dive/cli/internal/ui/v1/app/app.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/app/app.go), which initializes a **gocui** GUI and enters the main rendering loop. The UI architecture separates concerns into distinct views:

- **Layer view**: [`cmd/dive/cli/internal/ui/v1/view/layer.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/view/layer.go) displays the list of image layers with size and command information
- **File-tree view**: [`cmd/dive/cli/internal/ui/v1/view/filetree.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/view/filetree.go) renders the browsable filesystem hierarchy
- **Layout manager**: [`cmd/dive/cli/internal/ui/v1/layout/manager.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/layout/manager.go) coordinates view positioning and resizing

The `UpdateAndRender` method continuously refreshes the display with the latest analysis state until the user triggers a quit event.

### Supporting Infrastructure (`internal/*`)

Shared utilities live in the `internal` directory to prevent external import:
- **Event bus**: [`internal/bus/bus.go`](https://github.com/wagoodman/dive/blob/main/internal/bus/bus.go) wraps **go-partybus** to decouple the analysis engine from UI updates using publish-subscribe patterns
- **Structured logging**: [`internal/log/log.go`](https://github.com/wagoodman/dive/blob/main/internal/log/log.go) provides centralized logging facilities
- **Utilities**: `internal/utils/` contains argument helpers and common view components

## How the Components Work Together

The execution flow demonstrates how the main components and packages in the Dive repository interact:

1. **Startup**: [`cmd/dive/main.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/main.go) creates the clio application and loads `v1.Config` from flags, environment variables, and configuration files via `cmd/dive/cli/internal/options/`.

2. **Image Resolution**: [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go) calls `DeriveImageSource` to detect whether the input is a Docker Engine reference, archive path, or Podman reference, then returns the concrete `image.Resolver` implementation.

3. **Layer Processing**: The resolver produces `[]*image.Layer`, where each `Layer` contains a `*filetree.FileTree`. The analysis code builds these trees layer by layer.

4. **Diff Calculation**: For each successive layer, `FileTree.CompareAndMark` annotates filesystem changes, allowing the UI to highlight added, removed, and modified files.

5. **Event Distribution**: Long-running analysis operations publish progress events via `internal/bus` so the UI can remain responsive and display status updates.

6. **Rendering**: [`ui/v1/app/app.go`](https://github.com/wagoodman/dive/blob/main/ui/v1/app/app.go) runs the main event loop, calling the controller's `UpdateAndRender` to refresh the terminal display with current layer and file-tree state.

## Working with the Dive API

### Resolving an Image and Listing Layers

This example demonstrates the core API for image resolution:

```go
import (
    "fmt"
    "github.com/wagoodman/dive/dive"
    "github.com/wagoodman/dive/dive/image"
)

func listLayers(imageRef string) error {
    // Detect the source (docker engine, archive, podman) and pick a resolver
    src, ref := dive.DeriveImageSource(imageRef)
    resolver, err := dive.GetImageResolver(src)
    if err != nil {
        return err
    }

    // Resolve the image – this pulls metadata and builds layer objects
    img, err := resolver.Resolve(ref)
    if err != nil {
        return err
    }

    // The Image struct contains a slice of *image.Layer
    for i, l := range img.Layers {
        fmt.Printf("Layer %d: %s (%s) – %d bytes\n",
            i, l.ShortId(), l.Command, l.Size)
    }
    return nil
}

```

*Relevant files*: [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go), [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go), [`dive/image/layer.go`](https://github.com/wagoodman/dive/blob/main/dive/image/layer.go).

### Accessing File-Tree Data

To inspect the filesystem of a specific layer:

```go
func printLayerTree(img *image.Image, layerIdx int) error {
    if layerIdx < 0 || layerIdx >= len(img.Layers) {
        return fmt.Errorf("invalid layer index")
    }
    ft := img.Layers[layerIdx].Tree          // a *filetree.FileTree
    fmt.Println(ft.String(true)) // true → show file size attributes
    return nil
}

```

*Relevant file*: [`dive/filetree/file_tree.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/file_tree.go).

### Programmatically Running the UI

To launch the interactive interface programmatically:

```go
func runUI() error {
    // The CLI package builds a v1.Config from flags / env vars
    cfg, err := v1.LoadConfig()
    if err != nil {
        return err
    }
    // UI entry point – blocks until the user quits (Ctrl+C)
    return v1.Run(context.Background(), cfg)
}

```

*Relevant file*: [`cmd/dive/cli/internal/ui/v1/app/app.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/app/app.go).

## Summary

- **`cmd/dive`**: Contains the application entry point ([`main.go`](https://github.com/wagoodman/dive/blob/main/main.go)), CLI command definitions, and configuration option structures that map flags to the core engine.
- **`dive/image`**: Provides pluggable image resolution through the `Resolver` interface, with concrete implementations for Docker Engine, Docker archives, and Podman.
- **`dive/filetree`**: Implements the in-memory filesystem model with diffing capabilities, efficiency calculations, and ASCII rendering for layer analysis.
- **`cmd/dive/cli/internal/ui/v1`**: Hosts the interactive terminal interface built on **gocui**, including views for layers, file trees, and the layout manager.
- **`internal/*`**: Supplies cross-cutting concerns including the event bus ([`internal/bus/bus.go`](https://github.com/wagoodman/dive/blob/main/internal/bus/bus.go)), structured logging, and utility helpers.

## Frequently Asked Questions

### What is the main entry point of the Dive application?

The entry point is [`cmd/dive/main.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/main.go), which constructs a **clio** application and registers the top-level `dive` command. This file handles the initial bootstrap before delegating to [`cmd/dive/cli/cli.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/cli.go) for command execution and configuration loading.

### How does Dive support multiple container engines?

Dive uses the `Resolver` interface defined in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go) to abstract image fetching. The function `dive.GetImageResolver` (in [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go)) selects between Docker Engine, Docker archive, and Podman resolvers based on the image reference format detected by `DeriveImageSource`.

### What library does Dive use for its terminal user interface?

Dive builds its interactive UI using **gocui**, a minimalist console UI library for Go. The main application logic resides in [`cmd/dive/cli/internal/ui/v1/app/app.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/app/app.go), which manages the event loop, keybindings, and view coordination through the layout manager.

### How does Dive calculate differences between image layers?

The `dive/filetree` package handles differential analysis. Each `image.Layer` contains a `*filetree.FileTree` representing that layer's filesystem state. The `FileTree.CompareAndMark` method (in [`dive/filetree/diff.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/diff.go) or related files) compares successive trees to annotate nodes as added, removed, or modified.