Folly: Meta's C++20 Component Library and the Cost of Depending on It
An open-source C++ library developed and used at Facebook.
At a glance
- What is it?
- Folly is a C++20 library of core components that Meta uses across its own open source C++ projects. It is a static-link dependency with no ABI stability between commits, and the README is explicit that you should treat it that way.
- Who is it for?
- Adopt Folly if you are already inside a Meta-adjacent C++ stack (Thrift, Fizz, Proxygen, Wangle) or you specifically need a component such as FBString or the folly synchronization primitives that std and Boost do not provide in the form you need.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap Folly fills between std and Boost
The README states Folly "complements (as opposed to competing against) offerings such as Boost and of course std." The stated rule is narrow: a component gets written only when what is needed is "either not available, or does not meet the needed performance profile," and components are meant to be removed if std or Boost obsoletes them. That is a different posture from a general utility library. It means the contents are shaped by Meta's production workloads rather than by a desire for coverage. The README points at PackedSyncPtr.h and SmallLocks.h as examples where "performance concerns permeate much of Folly, sometimes leading to designs that are more idiosyncratic than they would otherwise be." Those two headers are the honest signal: this is a library where a pointer is packed with a synchronization word, and where a lock is small enough that the size itself is the design constraint. If your project does not have that constraint, the idiosyncrasy is cost without benefit.
Who this library is actually for
Folly is for engineers writing C++20 who need a specific primitive that the standard library does not ship, and who can accept a source-level dependency rather than a stable binary one. The README says Folly is "often a dependency of Facebook's other open source C++ efforts and place where those projects can share code." That sentence is the clearest statement of the intended audience: if you are building on Thrift, Fizz, Proxygen or Wangle, Folly is already in your dependency graph and adopting it directly changes nothing about your build's shape. If you are not, you are taking on a dependency whose upgrade story is defined by the absence of guarantees. The namespace convention reinforces the boundary. All symbols live in namespace folly, with internal namespaces such as internal and detail, and the README says user code should not depend on symbols in those namespaces. That is a normal arrangement, but it also means the surface you may rely on is the one the project chooses to keep public, and it can shrink.
Flat layout, stuttering include paths, and the experimental trap
The physical design is deliberately plain. Folly uses what the README calls the classic "stuttering" scheme folly/folly, where the first directory is the installation root and the second distinguishes the library at include time, giving paths like #include <folly/FBString.h>. The directory structure is flat, mirroring the namespace structure, and the README notes it is possible this will change in future versions. Two subdirectories matter for anyone deciding what to depend on. folly/experimental contains files used inside Folly and possibly at Meta but not considered stable enough for client use, and the README is direct: "Your code should not use files in folly/experimental lest it may break when you update Folly." folly/folly/test holds unittests named ComponentXyzTest.cpp for each ComponentXyz.*, and folly/folly/docs holds documentation. The practical consequence is that the header path itself tells you your risk level, and there is no packaging mechanism that enforces the distinction for you.
Building it with getdeps.py, and why the install location matters
The documented path is getdeps.py, which the README describes as a script used by many of Meta's OSS tools that downloads and builds dependencies first and then invokes cmake. It requires python3.6 or later on PATH and works on Linux, macOS and Windows. On Linux or macOS with homebrew, the README gives sudo ./build/fbcode_builder/getdeps.py install-system-deps --recursive after cloning, with a --dry-run flag to inspect packages first. The build command is python3 ./build/fbcode_builder/getdeps.py --allow-system-packages build, and output lands at installed/folly/lib/libfolly.a. Dependencies named in the README include a version of boost compiled with C++14 support and googletest for the tests. The build settings live in the getdeps manifest build/fbcode_builder/manifests/folly, which the README says you can edit locally. The most consequential instruction is about installation: because Folly provides no compatibility guarantees between commits, the README recommends building and installing to a temporary location and pointing your project's build at it, for example via CMAKE_PREFIX_PATH, rather than installing into system directories. You can locate that temporary tree with python3 ./build/fbcode_builder/getdeps.py show-inst-dir, and find the scratch build directory with show-build-dir, which also contains a run_cmake.py for iterating. Tests run through python3 ./build/fbcode_builder/getdeps.py --allow-system-packages test. The README also mentions build.sh and build.bat, but the supplied text is truncated there, so the exact contents of those scripts cannot be confirmed from this material.
The ABI decision is the whole adoption decision
The README states plainly that Folly does not provide any ABI compatibility guarantees from commit to commit and generally recommends building it as a static library. That single sentence determines most of the operational cost. A static link means Folly's code is compiled into your binary, so an upgrade requires recompiling your translation units that include Folly headers, not just swapping a shared object. It also means two libraries in the same process can each carry their own Folly without symbol collisions, which is the reason the recommendation exists. The cost is build time and binary size, and it grows with how much of Folly you touch. The release cadence visible in the repository is weekly, with tags in a date-based form such as v2026.09.07.00. Nothing in the material says you must track that cadence, but it does mean the distance between the commit you pin and current main widens quickly. There is no documented long-term support branch in the supplied material, so pinning means pinning and owning the backport yourself.
Where Folly is the wrong tool
Folly is a poor fit when your project needs a stable binary interface. If you ship a shared library to third parties and expose Folly types in your public headers, the absence of ABI guarantees between commits turns every Folly bump into a coordinated release with your consumers. The README's own advice to install to a temporary location and point CMAKE_PREFIX_PATH at it is a workaround for exactly this, and a workaround is a signal. It is also a poor fit when the component you want already exists in std or Boost in an adequate form. The README's stated policy is to remove components when std or Boost obsoletes them, which means any given component may be on a path to deprecation, and betting on it is betting against the project's own stated direction. Finally, the platform support deserves a careful read. The README says Folly supports gcc 5.1+, clang, or MSVC and should run on Linux, iOS, macOS and Windows x86-64, but it also says the CMake build is only tested on some of these platforms, aiming at minimum for macOS and Linux on the latest Ubuntu LTS or newer. "Should run" and "is tested" are different claims, and the gap is where your build breakage lives.
Boost and std as the comparison, and what the difference actually is
The natural alternative is Boost, and the README frames the relationship rather than hiding it: Folly complements Boost, and components are written only when Boost or std does not meet the needed performance profile. The difference in approach is governance and scope. Boost is a collection of separately reviewed libraries with a long history of interface stability and a wide platform matrix. Folly is a single repository with no internal dependency restrictions, meaning any Folly module may use any other Folly component, and a flat directory structure that mirrors one namespace. That internal freedom is what allows a header like SmallLocks.h to exist at all, because a component can reach into another component's internals without negotiating an interface boundary. The trade is that you cannot take one Folly component in isolation as cleanly as you can take one Boost library, and the README confirms there is no restriction on internal dependencies. If you want a small, stable, independently versioned piece of functionality, Boost's model fits better. If you want the thing Meta built because the existing options were too slow at Meta's scale, Folly is the only place that thing exists.
Maintenance cost and licence
The maintenance burden is dominated by the rebuild-on-upgrade model described above. Because Folly is built as a static library with no ABI guarantees between commits, the recurring cost is compile time in your own build, not a dependency resolution step. The getdeps.py path mitigates part of this by pinning dependency versions for you: the README says the script takes into account what versions are installed locally and otherwise downloads and builds them, including a Boost compiled with C++14 support. That reduces the chance of a version mismatch but adds a full Boost build to any environment where system packages are unavailable, which is why the README offers install-system-deps as the first step on Linux and macOS. Folly is licensed under Apache-2.0, which is a permissive licence that permits use in proprietary software and requires preservation of notices. This article is not legal advice; if you redistribute Folly in binary form, read the licence text and your organisation's policy before relying on that summary.
Editorial conclusion
Adopt Folly if you are already inside a Meta-adjacent C++ stack (Thrift, Fizz, Proxygen, Wangle) or you specifically need a component such as FBString or the folly synchronization primitives that std and Boost do not provide in the form you need. Do not adopt it as a general-purpose utility library for a small project: the getdeps.py build pulls in a Boost compiled with C++14 support and googletest, and the README states there are no ABI compatibility guarantees from commit to commit, so every upgrade is a rebuild of your own code. Before committing, clone the repository, run python3 ./build/fbcode_builder/getdeps.py --allow-system-packages build, then check python3 ./build/fbcode_builder/getdeps.py show-inst-dir to confirm libfolly.a landed where you expect, and read folly/docs/Overview.md to see whether the specific header you want is stable or lives under folly/experimental.
Community notes