Dive Tool Usage Patterns and Examples: A Complete Guide

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 to fetch image metadata and layer tarballs. Each layer is parsed by the file-tree comparer in 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.

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 loads tarballs directly, while Podman users can specify --source podman to utilize the resolver implemented in dive/image/podman/resolver.go.


# 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, 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.

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.

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.

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, allowing customization of the terminal interface without recompiling.

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

Summary

  • Layer-by-layer inspection via dive/image/resolver.go and 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 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.
  • 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 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 handles tar archives, while 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, 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, allowing you to remap controls or hide specific diff views like "removed" entries.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →