layerx
Interactive Docker image layer inspector with CI-friendly efficiency checks. Single binary, no runtime dependencies beyond Docker.

What is layerx?
A terminal tool for understanding what's inside a Docker image — which layer added each file, where the wasted bytes are, and what your RUN steps actually produced.
Use it to:
- Debug bloated images and find the layer responsible
- Review the filesystem impact of a Dockerfile change before merging
- Gate CI on layer waste or efficiency thresholds
Quick Start
# macOS / Linux
brew install deveshctl/tap/layerx
# Try it
layerx nginx:latest
Other platforms: see Install.
What you can do
| Mode |
Command |
Best for |
| Interactive |
layerx IMAGE |
Exploring layers, diffs, file contents, wasted bytes |
| CI |
layerx ci IMAGE or CI=true layerx IMAGE |
Pipeline gates on efficiency / wasted bytes |
| Export |
layerx --json out.json IMAGE |
Scripts, dashboards, jq |
Interactive explorer
- Browse layers with vim keys; see Dockerfile command, size, short digest
- Per-layer file tree with diff colouring (green = added, yellow = modified, red = removed)
- Open files inline with line numbers, scrolling, and in-viewer search
- Sort by size, filter by name, hide unchanged files
- Extract a file to disk, copy a path, or copy file contents to your clipboard (works over SSH and tmux)
- Efficiency score and wasted bytes always visible in the status bar
See TUI keybindings for the full shortcut list.
CI mode
- Three configurable rules: lowest efficiency, highest wasted bytes, highest user-wasted percent
- Exits
0 on pass, 1 on rule failure, 2 on internal error
- Configurable via
.layerx.yaml or CLI flags
JSON export
Full analysis (layers, files, efficiency) as JSON — pipe through jq for scripted checks.
Prerequisites
Docker must be installed and running.
Install
Homebrew (macOS & Linux)
brew install deveshctl/tap/layerx
Scoop (Windows)
scoop bucket add layerx https://github.com/deveshctl/scoop-bucket
scoop install layerx
Debian / Ubuntu
# amd64
curl -LO https://github.com/deveshctl/layerx/releases/latest/download/layerx_linux_amd64.deb
sudo dpkg -i layerx_linux_amd64.deb
# arm64
curl -LO https://github.com/deveshctl/layerx/releases/latest/download/layerx_linux_arm64.deb
sudo dpkg -i layerx_linux_arm64.deb
RHEL / Fedora
# amd64
curl -LO https://github.com/deveshctl/layerx/releases/latest/download/layerx_linux_amd64.rpm
sudo rpm -i layerx_linux_amd64.rpm
# arm64
curl -LO https://github.com/deveshctl/layerx/releases/latest/download/layerx_linux_arm64.rpm
sudo rpm -i layerx_linux_arm64.rpm
Direct download
Prebuilt binaries for Linux, macOS, and Windows (amd64 + arm64) on the Releases page. For a specific version, replace latest with the tag (e.g. v1.2.2) in the URLs above.
Build from source
Requires Go 1.26+:
go install github.com/deveshctl/layerx@latest
Usage
# Interactive TUI
layerx nginx:latest
# Force a fresh analysis (bypass the cache)
layerx --no-cache nginx:latest
# CI mode — exit 1 if efficiency < 95%
layerx ci --lowest-efficiency 0.95 nginx:latest
# JSON export
layerx --json analysis.json nginx:latest
# Shell completion (bash)
source <(layerx completion bash)
TUI keybindings
| Key |
Action |
Tab |
Switch panel (layers ↔ file tree) |
j / k |
Move up / down |
g / G |
Jump to top / bottom |
Enter |
Open file viewer; expand or collapse a folder |
Esc |
Back (close search → close viewer → clear filter → quit) |
/ |
Filter file tree (tree) / search in viewer (viewer) |
n / N |
Next / previous search match (viewer) |
y |
Copy file path to clipboard |
Y |
Copy file content (viewer) or layer command (layers) |
d |
Toggle diff-only mode (hide unchanged files) |
s |
Cycle sort: default → largest → smallest |
x |
Extract focused file to disk |
? |
Toggle help overlay |
q |
Quit |
CI mode
GitHub Actions
- name: Install layerx
run: |
curl -LO https://github.com/deveshctl/layerx/releases/latest/download/layerx_linux_amd64.deb
sudo dpkg -i layerx_linux_amd64.deb
- name: Check image efficiency
run: layerx ci --lowest-efficiency 0.95 myapp:${{ github.sha }}
Configuration
Drop a .layerx.yaml in your project root:
rules:
lowest-efficiency: 0.9
highest-wasted-bytes: 52428800 # 50MB
highest-user-wasted-percent: 0.1
CLI flags override config-file values. Setting a threshold to 0 or negative disables that rule.
Caching & environment
| Variable |
Purpose |
CI=true |
Treat layerx IMAGE (no subcommand) as layerx ci IMAGE |
LAYERX_CACHE_DIR |
Override the default analysis cache directory |
Repeat runs against an unchanged image digest reuse the cache and skip the tar export and parse. --no-cache (alias --refresh) bypasses the cache for a single run; the run still refreshes the cache on success.
Troubleshooting
- "Cannot connect to the Docker daemon" — Docker isn't running. Start Docker Desktop, or
sudo systemctl start docker on Linux.
- "image not found" — layerx pulls images on demand. Check the reference and that you can
docker pull it manually.
- Cache permission errors — point
LAYERX_CACHE_DIR somewhere writable, e.g. LAYERX_CACHE_DIR=$HOME/.cache/layerx.
Contributing
Issues and PRs welcome. For larger changes, please open an issue first to discuss the approach. See CHANGELOG for release notes.
Architecture
image/ Domain layer — Docker SDK, tar parsing, file tree, efficiency
tui/ Bubbletea v2 TUI — consumes image/ interfaces only
ci/ CI evaluator — consumes image/ interfaces only
cmd/ Cobra CLI — wires packages together
config/ .layerx.yaml loader
Design rules:
image/ has zero imports from tui/, ci/, or config/
- TUI and CI consume interfaces, never concrete Docker SDK types
- All Docker client calls negotiate the API version (no breakage on Docker Engine upgrades)
- Both whiteout conventions handled correctly (regular and opaque)
Tech stack
License
MIT