Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/leanprover/lean4/llms.txt

Use this file to discover all available pages before exploring further.

Lake (Lean Make) is the official build system and package manager bundled with every Lean 4 installation. It reads a configuration file — called a lakefile — from the root of your project, resolves dependencies, compiles Lean source files in the correct order, and links the resulting artifacts into libraries or executables. If you have installed Lean 4 through elan, you already have Lake. Lake configuration files can be written in TOML (the default for new projects) or in the Lean DSL itself. Both formats support the same feature set; TOML is more approachable for beginners while the Lean DSL gives you the full power of metaprogramming for advanced use cases.
The lakefile is conventionally stored in the root directory of a package and is named lakefile.toml (TOML) or lakefile.lean (Lean DSL). Lake automatically discovers it when you run any lake command in or below that directory.

Key Concepts

Understanding Lake requires familiarity with a handful of well-defined terms. The table below gives a concise definition; the accordion sections that follow provide additional detail.
TermOne-line definition
PackageThe fundamental unit of code distribution in Lake
LakefileThe configuration file that describes a package
WorkspaceA root package together with all of its transitive dependencies
ModuleThe smallest build unit — typically one Lean source file
LibraryA named collection of modules with a shared configuration
ExecutableA binary built from a single Lean module that has a main definition
TargetAny named, buildable unit — libraries, executables, and custom targets
FacetOne specific build product of a target (e.g. the static facet of a library)
DependencyAnother package that the current package requires
Manifestlake-manifest.json — records the exact resolved revisions of all dependencies
TraceA hash used to determine whether a target is up-to-date
ReservoirThe official Lean package registry at reservoir.lean-lang.org
A package is the fundamental unit of code distribution in Lake. Packages can be sourced from the local file system or downloaded from the web (for example, via Git). A package is identified by the name field in its lakefile. Package names must be unique across all packages in a dependency graph.
A workspace is the broadest organisational unit in Lake. It bundles together a root package, its transitive dependencies, and Lake’s environment. Every package can operate as the root of a workspace and the workspace derives its packagesDir configuration from this root. When you run lake build inside a package directory, that package becomes the workspace root.
A module is the smallest unit of code visible to Lake’s build system. It is generally represented by a single Lean source file (.lean). Lake builds a set of binary artefacts for each module: a .olean (Lean data for importers), an .ilean (metadata for the LSP), and optionally a compiled C file and native object. Modules can import one another; Lake resolves the import graph automatically.
A Lean library is a collection of modules that share a single build configuration. Its configuration defines a set of module roots (determining which modules belong to the library) and module globs (selecting which modules are built on lake build). Libraries produce static and shared binary facets in addition to their Lean artefacts.
A Lean binary executable is a binary that users can run without Lean installed. It is built from a Lean module called its root, which must contain a main definition. The root’s transitive local imports are built and linked automatically.
A target is the fundamental build unit of Lake. Each target has a name used to identify it on the command line (e.g. lake build MyLib). Complex build products like packages and libraries have multiple facets — for example, a library has a leanArts facet (.olean/.ilean files), a static facet (.a), and a shared facet (.so/.dll/.dylib).Targets and facets are referenced with the syntax:
[@[<package>]/][<target>|[+]<module>][:<facet>]
SpecifierMeaning
MyLibDefault facet(s) of target MyLib
@myPkgDefault target(s) of package myPkg
+MyModuleDefault facet(s) of module MyModule
@myPkg/+MyModule:cThe C file facet of MyModule in package myPkg
A dependency is another Lake package that the current package needs in order to build. Dependencies can come from a local path, a Git repository URL, or Reservoir. Once resolved, the exact Git revision (or local path) of each dependency is recorded in lake-manifest.json. This manifest ensures reproducible builds — every developer and CI run uses the same versions. Running lake update is the only command that modifies the manifest.
A trace is a hash derived from all the inputs to a build target — its source file, the Lean toolchain version, its imports, compiler flags, etc. Lake stores the trace alongside each built artefact. On subsequent builds, Lake recomputes the trace and compares it to the stored value; if they match the target is up-to-date and is not rebuilt.

The .lake/ Directory

Lake stores all build outputs and downloaded packages inside a .lake/ directory at the root of the package:
.lake/
  build/          # compiled artefacts
    bin/          # binary executables
    lib/          # native libraries (.a, .so, .dll)
    lib/lean/     # Lean binary artifacts (.olean, .ilean)
    ir/           # intermediate results (.c, .o files)
  packages/       # downloaded dependencies
Add .lake/ to your .gitignore. Lake creates and manages this directory automatically; its contents should not be committed to source control (except for lake-manifest.json, which should always be committed).

Configuration File Formats

Lake accepts configuration files in two formats. Both are functionally equivalent.
name = "hello"
version = "0.1.0"
defaultTargets = ["hello"]

[[lean_lib]]
name = "Hello"

[[lean_exe]]
name = "hello"
root = "Main"
TOML is the default format for lake new and lake init. It uses standard TOML array-of-tables syntax ([[lean_lib]], [[lean_exe]], [[require]]) for multi-valued entries.
You can convert between formats at any time with the lake translate-config command:
# Convert the current lakefile.lean to lakefile.toml
lake translate-config toml

# Convert the current lakefile.toml to lakefile.lean
lake translate-config lean
Translation is lossy — comments and formatting are not preserved.

Next Steps

Ready to create your first package? Head over to the Creating Packages guide to scaffold a new project with lake new or lake init.

Build docs developers (and LLMs) love