What is BuildKit, and how does it improve on the legacy builder?
Quick Answer
BuildKit is Docker's modern build engine (the default since Docker 23.0), replacing the older, simpler legacy builder with meaningfully better performance (parallel execution of independent build stages, smarter cache handling) and new capabilities the legacy builder never had at all — including build secrets (see the security topic), cache mounts for persisting package manager caches across builds, and the multi-architecture building that buildx relies on (see the registries topic). Most day-to-day Dockerfile syntax works identically either way, but BuildKit unlocks meaningfully better performance and a set of genuinely new, previously-impossible capabilities.
Detailed Answer
What changed, and why it matters
The legacy Docker builder processed a Dockerfile's instructions largely sequentially, one after another. Even independent build stages in a multi-stage build (see that question), which had no actual dependency on each other, were still built one at a time. BuildKit can analyze the full dependency graph of a build and execute genuinely independent parts in parallel, meaningfully speeding up builds with multiple, unrelated stages.
FROM node:20 AS frontend-build
WORKDIR /frontend
COPY frontend/ .
RUN npm run build
FROM golang:1.22 AS backend-build
WORKDIR /backend
COPY backend/ .
RUN go build -o server .
FROM alpine:3.19
COPY --from=frontend-build /frontend/dist /app/static
COPY --from=backend-build /backend/server /app/server
With BuildKit, the frontend-build and backend-build stages have no dependency on each other at all, so they can build simultaneously rather than following the legacy builder's strictly sequential approach. On a multi-core build machine, this can meaningfully cut overall build time for Dockerfiles with genuinely parallel, independent stages.
New capabilities the legacy builder simply didn't have
Build secrets (covered in the security topic's question):
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) npm install
No equivalent existed in the legacy builder — this specific, secure secret-handling mechanism is BuildKit-exclusive.
Cache mounts — persisting a package manager's download cache across builds, even when the surrounding layer itself must rebuild:
RUN --mount=type=cache,target=/root/.npm \
npm ci
This directory persists across builds independent of Docker's normal layer caching. This is useful specifically when the layer itself must re-execute (for example, when the lockfile changed) but you still want to avoid re-downloading already-fetched package versions from the network.
Multi-architecture builds via buildx (see that question) — building for multiple CPU architectures in a single command and pushing one combined manifest, a capability built directly on BuildKit's architecture.
Smarter, more granular caching
BuildKit's caching model is more sophisticated than the legacy builder's simple sequential layer cache. In some configurations, it can cache and reuse results at a finer granularity. It also supports exporting and importing build cache to and from a remote location. This is useful in CI, where a fresh build environment might otherwise start with no local cache at all. Pulling a previously-exported cache from a registry lets CI builds benefit from caching, even without persistent local disk state between runs.
How to tell if you're using it (and why you almost certainly already are)
docker build -t myapp .
# BuildKit has been the DEFAULT build engine since Docker 23.0 -- most users
# are already using it without any explicit configuration required
Since Docker version 23.0, BuildKit is the default builder for docker build. Most developers today are already benefiting from it without ever having explicitly enabled anything. On genuinely older Docker installations, it historically required setting DOCKER_BUILDKIT=1 explicitly, or using docker buildx build directly. Its presence is mostly transparent day to day. The practical value in knowing it exists comes from reaching for its newer, exclusive capabilities specifically — build secrets, cache mounts — when a build actually needs them.