Est. 2013 Intermediate

Buck

Facebook's fast, modular build system inspired by Google Blaze, designed for large monorepos with parallel builds and reproducible outputs.

Created by Michael Bolin (Facebook)

Paradigm Declarative
Typing N/A (Build Tool)
First Appeared 2013
Latest Version v2022.05.05.01 (final Buck1 release, August 2022)

Buck is a build automation system created at Facebook in 2012 and open-sourced on GitHub in April 2013, with a formal announcement on the Facebook Engineering blog in May 2013. Designed for large-scale monorepo development, Buck introduced an artifact-based, declarative build model to mobile app development — enabling parallel builds, incremental compilation, and reproducible outputs across Java, Android, iOS, and many other languages. Buck’s significance in the broader build tooling ecosystem was notable: it predated Google’s public release of Bazel by approximately two years, though both Buck and Bazel share the same intellectual lineage as Google’s internal Blaze system, each developed as an independent descendant. As of late 2023, Buck itself has been retired and archived, superseded by Buck2, Meta’s complete Rust-based rewrite released in April 2023.

History & Origins

The Problem Buck Was Built to Solve

In 2012, Facebook’s Android engineering team was building large applications using Ant, the standard Android build tool of the era. Ant had three critical problems at Facebook’s scale: it was unsound (rebuilding more than necessary because it used file timestamps rather than content to detect changes), it was slow as a direct consequence of being unsound (unnecessary rebuilds cascaded through the dependency graph), and it used XML as its build language, which made build files verbose and hard to reason about at scale.

There was a deeper structural problem too. Ant builds could reference large “lib” directories without explicit dependencies, encouraging teams to bundle many unrelated classes together in flat library JARs rather than create many small, well-defined modules. This anti-pattern made it impossible to build only the code that had actually changed.

Hackathon Origins

Michael Bolin, a Facebook software engineer, created the first Buck prototype during Facebook’s annual summer hackathon in July 2012. By the end of the hackathon he had a working build system, and within weeks it was adopted as Facebook’s official Android build tool. The system drew direct inspiration from Google’s internal Blaze build system — the same system that Google would eventually open-source as Bazel in 2015. Several Facebook engineers had previously worked at Google, bringing knowledge of Blaze’s artifact-based design philosophy.

Facebook documented concrete performance results from the migration in the original 2013 announcement: build times for the main Facebook Android app dropped from 3 minutes 40 seconds to 1 minute 30 seconds (per the Facebook Engineering blog post). According to InfoQ’s coverage of Bolin’s DevCon NYC presentation, parallel unit test execution dropped from 20 minutes to 4 minutes with 8 threads. These improvements reflected Buck’s content-addressed caching and fine-grained modularization, not simply faster hardware.

Open Source Release

Buck was open-sourced on GitHub in April 2013, with a formal announcement on the Facebook Engineering blog on May 14, 2013. The announcement explicitly credited Blaze as Buck’s inspiration and described the core philosophy: “favoring the creation of many small modules rather than a handful of large modules.” At the time of open-sourcing, Buck was also expanding beyond Android to support pure Java projects, with iOS support under development.

Design Philosophy

Buck is built around an artifact-based, declarative model that stands in deliberate contrast to task-based build tools like Ant and Make.

Artifacts, Not Tasks

In a task-based build tool (Make, Ant), a build file describes how to do work — a sequence of imperative steps. In Buck, a build file describes what to build and what it depends on. Buck then determines the how: it constructs a directed acyclic graph (DAG) of all build targets and their dependencies, resolves which artifacts are out of date, and executes only the necessary build steps.

This distinction matters for correctness and performance. Because Buck knows exactly which outputs depend on which inputs, it can:

  1. Rebuild only what changed — not just the file that changed, but only the downstream targets that depend on that artifact.
  2. Build in parallel — independent targets in the dependency graph can be built simultaneously, fully utilizing available CPU cores.
  3. Produce reproducible outputs — build results depend on the content of declared inputs, not the order of execution or undeclared file system state.

Enforced Modularity

Buck’s design enforces fine-grained module boundaries. Every BUCK file explicitly lists the sources and dependencies of each build target using formal deps declarations. You cannot depend on code you haven’t explicitly declared a dependency on. This enforcement makes it structurally impossible to accidentally use a transitive dependency directly, and it means the dependency graph is always an accurate picture of the actual code structure.

Content-Based Caching

Buck uses content hashes rather than file timestamps to determine whether a cached build result is still valid. This makes incremental builds more accurate: renaming a file, touching it, or reverting it to its previous content all produce the correct result without unnecessary rebuilds.

BUCK Files and Build Language

Build rules are defined in files named BUCK, placed in each directory of the project tree. BUCK files use a Python-derived syntax to declare build targets:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
android_library(
    name = 'activity',
    srcs = glob(['*.java']),
    deps = [
        '//java/com/example/model:model',
        '//third-party:gson',
    ],
    visibility = [
        'PUBLIC',
    ],
)

android_binary(
    name = 'app',
    manifest = 'AndroidManifest.xml',
    deps = [
        ':activity',
    ],
)

Each rule has a name within its directory, and targets are addressed using //path/to/dir:name syntax. The double-slash prefix refers to the project root, making target addresses stable regardless of where Buck is invoked from.

From Python DSL to Skylark

The original BUCK file format was a Python DSL evaluated by Jython. While convenient for developers familiar with Python, this approach had a fundamental problem: Python allows arbitrary code execution at parse time. A BUCK file could read environment variables, make network calls, or produce different results depending on the execution environment — all without Buck’s knowledge. This made builds non-deterministic and BUCK files hard to analyze statically.

To address this, Buck adopted Skylark (a configuration language created by Google for the Bazel project and later standardized as Starlark) as the preferred BUCK file language. Skylark is a deliberately restricted subset of Python: it removes top-level conditionals, unbounded loops, classes, exception handling, regular expressions, and access to the host environment. These restrictions enable deterministic parsing, safe parallel evaluation of BUCK files, and reliable static analysis of the dependency graph. Buck supported “polyglot parsing” to allow gradual migration from the old Python DSL to Skylark.

Key Features

Parallel and Incremental Builds

Buck builds all independent targets in a dependency graph simultaneously, using as many cores as are available. Combined with content-addressed caching, this means large monorepos can achieve fast incremental builds even as the codebase grows.

buck query: Dependency Graph Analysis

The buck query command exposes the build dependency graph as a queryable database. It supports operations such as finding all targets that depend on a specific library (rdeps), finding the transitive closure of dependencies for a target (deps), and computing set operations over query results. This is particularly useful for understanding the impact of a code change before building.

buck project: IDE Integration

The buck project command generates IDE project files (IntelliJ, Xcode) derived from the BUCK dependency graph. This ensures that IDE configurations stay in sync with the actual build definitions rather than diverging into a separate, often incorrect representation.

Multi-Language Support

Buck grew from Android-only roots to support a broad range of source languages and target platforms. By the time of its final release, Buck supported building code written in Java, Kotlin, C++, Python, Go, Rust, Swift, Objective-C, OCaml, Lua, and others. Target platforms included Android, iOS, JVM, and native binaries.

Remote Caching

Buck supports a shared artifact cache that allows teams to reuse build outputs produced by other developers or CI machines. When a build target’s inputs haven’t changed since a previous build (anywhere in the organization), Buck can retrieve the cached output rather than rebuilding it.

Evolution

Early Growth (2013–2015)

After open-sourcing in 2013, Buck expanded rapidly beyond its Android origins. iOS support arrived, enabling Facebook’s iOS engineers to use the same build system as the Android team. Third-party adoption began, with companies such as Uber and Airbnb migrating their mobile build pipelines to Buck.

Skylark Migration (2015–2018)

The shift from the original Python DSL to Skylark was a significant engineering investment driven by the need for deterministic, analyzable build files. Buck introduced Skylark support and then worked to migrate internal Facebook BUCK files while providing tooling to assist external users in migrating their own files.

Maintenance Phase and Buck2 Development (2019–2022)

As Meta grew, the limitations of Buck1’s architecture became apparent at the scale of hundreds of millions of lines of code. Performance problems and architectural constraints — particularly around the separation between the parsing and execution phases of a build — motivated a complete redesign rather than incremental improvement. Meta began developing Buck2 internally, and Buck1’s last release (v2022.05.05.01) was published in August 2022 without any public announcement of its finality.

Buck2 and Retirement (2023)

On April 6, 2023, Meta open-sourced Buck2, a complete from-scratch rewrite of the build system in Rust. Buck2 is not a fork or evolution of Buck1; it shares the same design philosophy but is architecturally unrelated. Meta stated that Buck1 had been “entirely phased out at Meta” by the time Buck2 was open-sourced. The original facebook/buck repository was archived as read-only on November 10, 2023.

Buck vs. Bazel

Buck and Bazel are the two best-known descendants of Google’s internal Blaze system, and they share a great deal of conceptual DNA: artifact-based builds, declarative BUCK/BUILD files, Starlark as the build file language, content-addressed caching, and the //package:target addressing scheme. They are not derived from each other — Buck predated Bazel’s public release by approximately two years — but both trace their philosophy back to Blaze.

The practical differences that historically distinguished them included:

AspectBuckBazel
LanguageJava (Buck1), Rust (Buck2)Java
Build file nameBUCKBUILD
Primary focusMobile (Android/iOS)Multi-platform
OrganizationFacebook/MetaGoogle
StatusArchived (Buck1); active (Buck2)Actively maintained

Current Relevance

Buck1 is no longer maintained. The repository has been archived, the official buck.build website states that “Buck is no longer actively maintained,” and the README directs users to Buck2. Projects that were using Buck1 have either migrated to Buck2 or to other build systems such as Bazel or Gradle.

Buck2 is the active successor. Released in April 2023, it is written in Rust, uses Starlark exclusively, decouples all language-specific rules from the core (implementing them in Starlark rather than Java), and provides built-in remote execution support. Meta uses Buck2 for all builds across its engineering organization.

For teams considering adoption, Buck2 is the appropriate system to evaluate. Teams already using Bazel may find migration costs high given the similarities in philosophy but differences in specifics.

Why It Matters

Buck’s significance in build tool history spans several dimensions:

  1. Popularizing artifact-based builds for mobile: Before Buck, large-scale mobile applications at companies like Facebook were built with Ant — a task-based tool that didn’t scale well. Buck demonstrated that the artifact-based model developed for server-side monorepos at Google could be applied successfully to mobile development.

  2. Predating Bazel’s public release: Buck was open-sourced in April 2013, nearly two years before Google open-sourced Bazel in March 2015. Both Buck and Bazel are independently derived from Google’s internal Blaze system rather than one influencing the other. The existence of Buck demonstrated that the Blaze philosophy could work outside Google, helping establish credibility for the broader class of Blaze-inspired build systems.

  3. Adopting the Starlark language: Starlark (originally called Skylark) was created by Google for the Bazel project as a restricted, deterministic Python subset for declarative build files. Buck subsequently adopted it to replace its own Python DSL. This shared adoption helped establish Starlark as the de facto standard for configuration DSLs in high-performance build tools.

  4. Demonstrating monorepo build patterns: Buck, alongside Bazel and Pants, helped popularize the technical patterns that make large monorepos tractable: explicit dependency declarations, fine-grained modules, content-addressed caching, and remote execution. These patterns influenced how many large engineering organizations structure their codebases.

  5. Buck2 as a systems programming showcase: Meta’s decision to rewrite Buck entirely in Rust, and to open-source that rewrite, produced one of the most widely-cited large-scale Rust projects in production. Buck2 has become a reference point in discussions about using Rust for developer tooling.

Timeline

2012
Michael Bolin creates the Buck prototype at Facebook's summer hackathon; adopted internally as Facebook's Android build tool by August 2012
2013
Buck open-sourced on GitHub (April); formally announced on the Facebook Engineering blog on May 14, 2013
2015
Google open-sources Bazel (March), its own descendant of the internal Blaze system that inspired Buck; Buck had predated Bazel's public release by approximately two years
2017
Skylark support introduced (approximately) as an alternative to the original Python DSL for BUCK files, enabling deterministic, sandboxed build rule evaluation; the exact year of Buck's Skylark integration is not precisely documented in public sources
2022
Final Buck1 release (v2022.05.05.01) published on August 8, 2022; active development of Buck ceases as Meta prepares Buck2
2023
Meta officially open-sources Buck2 on April 6, 2023 — a complete rewrite in Rust — and phases out Buck1 entirely across all Meta products
2023
facebook/buck GitHub repository archived as read-only on November 10, 2023; README updated to state 'This repo is dead'

Notable Uses & Legacy

Facebook / Meta

Buck was used to build all of Meta's major mobile apps, including Facebook, Messenger, Instagram, Workplace, and Ads Manager for both Android and iOS

Uber

Uber adopted Buck to build its iOS and Android applications, including the Uber rider app, Uber Partner, UberEATS, and Uber Freight; documented on the official Buck showcase

Airbnb

Airbnb used Buck for its iOS codebase; according to the official Buck Build Tool page, Airbnb reported approximately 50% faster CI builds and a 30% smaller app size after migration; the Airbnb Tech Blog also published a post on building mixed-language iOS projects with Buck

Lyft

Lyft adopted Buck for mobile builds and was listed on the official Buck showcase alongside Facebook and Uber

Language Influence

Influenced By

Google Blaze Python Make

Influenced

Buck2

Running Today

Run examples using the official Docker image:

docker pull
Last updated: