# Dive Tool Usage Patterns and Examples: A Complete Guide

> Explore common Dive tool usage patterns and examples for Docker image inspection, CI enforcement, and programmatic analysis. Streamline your workflow with this comprehensive guide.

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

---

**The Dive CLI supports interactive layer-by-layer Docker image inspection, CI-driven efficiency enforcement, and programmatic analysis through a unified pipeline involving image resolution, file-tree comparison, and configurable UI rendering.**

The **Dive** tool from the `wagoodman/dive` repository is a Go-based CLI utility that dissects Docker and OCI images to reveal wasted space and filesystem changes across layers. Whether you are optimizing container builds or enforcing size budgets in pipelines, understanding these **Dive tool usage patterns and examples** helps you integrate layer analysis into development workflows.

## Interactive Image Inspection Patterns

### Analyzing Local Docker Images

The most common pattern involves inspecting existing images directly from the Docker daemon. When you run `dive nginx:latest`, the tool invokes the engine resolver defined in [`dive/image/docker/engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/engine_resolver.go) to fetch image metadata and layer tarballs. Each layer is parsed by the file-tree comparer in [`dive/filetree/comparer.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/comparer.go), which tracks added, removed, and modified files to render the interactive terminal interface defined 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).

```bash
dive alpine:3.18

```

### Working with Docker Archives and Alternative Sources

For environments without a running Docker daemon, Dive supports archive-based resolution. The archive resolver in [`dive/image/docker/archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/archive_resolver.go) loads tarballs directly, while Podman users can specify `--source podman` to utilize the resolver implemented in [`dive/image/podman/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/podman/resolver.go).

```bash

# Analyze a saved tarball without Docker daemon

dive myimage.tar --source docker-archive

# Use Podman as the image source (Linux/macOS)

dive myimage --source podman

```

## Build-and-Inspect Workflows

The `build` command integrates container construction with immediate analysis. Implemented in [`cmd/dive/cli/internal/command/build.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/command/build.go), this pattern executes Docker or Podman builds, captures the resulting image ID, and automatically passes it to the analysis pipeline. This eliminates manual intermediate steps when optimizing Dockerfiles.

```bash
dive build -t myapp .

```

## CI/CD Integration and Efficiency Enforcement

In automated pipelines, Dive operates in headless mode when the `CI=true` environment variable is set. The UI is bypassed, and the tool evaluates rules defined in a `.dive-ci` configuration file, exiting with code 1 if thresholds for efficiency or wasted bytes are violated. This pattern leverages the same core analysis pipeline as interactive mode but disables rendering via [`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).

```bash
cat > .dive-ci <<EOF
rules:
  highestWastedBytes: 20MB
  lowestEfficiency: 0.95
EOF

CI=true dive myimage --ci-config .dive-ci

```

## Programmatic Usage and Custom Tooling

Advanced users can embed Dive's analysis engine into Go applications. By importing the internal packages, you can instantiate resolvers and run analyses without the terminal UI. The following example demonstrates creating a Docker resolver via `adapter.NewResolver`, loading configuration, and executing a headless analysis.

```go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/wagoodman/dive/cmd/dive/cli/internal/command/adapter"
	"github.com/wagoodman/dive/internal/bus"
	"github.com/wagoodman/dive/internal/config"
	"github.com/wagoodman/dive/internal/ui"
)

func main() {
	// Resolve the image using the Docker engine resolver
	resolver, err := adapter.NewResolver("docker")
	if err != nil {
		panic(err)
	}
	
	imageRef := "nginx:latest"
	image, err := resolver.Resolve(context.Background(), imageRef)
	if err != nil {
		panic(err)
	}

	// Configure for CI mode (headless)
	cfg := config.Default()
	cfg.CI = true
	
	if path := os.Getenv("DIVE_CI_CONFIG"); path != "" {
		if err := cfg.Load(path); err != nil {
			panic(err)
		}
	}

	// Run analysis without UI
	analysis := ui.NewAnalysis(cfg, bus.New())
	if err := analysis.Run(context.Background(), image); err != nil {
		panic(err)
	}

	if analysis.HasFailures() {
		os.Exit(1)
	}
	fmt.Println("Image passes all Dive CI checks")
}

```

## Configuration and Customization

Dive merges user-provided YAML configurations with defaults to modify behavior. You can override key bindings, adjust pane widths, or hide specific diff types using the `--config` flag. The configuration parsing logic resides in the `config` package and [`cmd/dive/cli/internal/ui/v1/config.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/config.go), allowing customization of the terminal interface without recompiling.

```bash
dive myimage --config ./custom-dive.yaml

```

## Summary

- **Layer-by-layer inspection** via [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go) and [`dive/filetree/comparer.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/comparer.go) forms the core of every Dive workflow.
- **Interactive analysis** uses the terminal UI 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) to visualize filesystem changes and efficiency scores.
- **CI enforcement** runs headless with `CI=true`, evaluating `.dive-ci` rules and returning non-zero exit codes on failure.
- **Build integration** through `dive build` combines construction and analysis in a single command handled by [`cmd/dive/cli/internal/command/build.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/command/build.go).
- **Programmatic access** allows embedding Dive's resolution and analysis pipeline into custom Go tooling via the `adapter` and `ui` packages.

## Frequently Asked Questions

### How does Dive calculate image efficiency?

Dive calculates efficiency by identifying duplicated files across layers, orphaned deletions, and unreferenced data. The [`dive/filetree/comparer.go`](https://github.com/wagoodman/dive/blob/main/dive/filetree/comparer.go) file builds cumulative file-trees for each layer to track these metrics, which the UI then renders as a percentage score based on wasted space analysis.

### Can Dive analyze images without a Docker daemon?

Yes. Dive supports `docker-archive` sources for tarballs and `podman` as alternative engines. The [`dive/image/docker/archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/archive_resolver.go) handles tar archives, while [`dive/image/podman/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/podman/resolver.go) interfaces with Podman on Linux and macOS systems, making the tool viable for daemon-less CI environments.

### What exit codes does Dive return in CI mode?

When running with `CI=true`, Dive exits with code 0 if all `.dive-ci` rules pass, and code 1 if any efficiency or wasted-space threshold is violated. This behavior is implemented in the analysis pipeline within [`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), ensuring reliable pipeline integration.

### How do I customize key bindings in the Dive UI?

Key bindings and pane layouts are controlled via YAML configuration files. Dive merges custom configurations specified with `--config` against defaults defined in the `config` package and [`cmd/dive/cli/internal/ui/v1/config.go`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/ui/v1/config.go), allowing you to remap controls or hide specific diff views like "removed" entries.