# How to Install fmtlib in C++ Projects: Complete Setup Guide

> Easily install fmtlib in C++ projects. Explore options like package managers, CMake FetchContent, or building from source for compiled or header-only modes.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-10

---

**You can install fmtlib via system package managers (apt, Homebrew, vcpkg, Conan), integrate it with CMake FetchContent, or build from source using the provided CMake targets that support both compiled library and header-only modes.**

fmtlib (also known as {fmt}) is a fast, type-safe C++ formatting library hosted at [fmtlib/fmt](https://github.com/fmtlib/fmt) that implements the C++20 `std::format` API. The library provides three primary installation strategies detailed in [`doc/get-started.md`](https://github.com/fmtlib/fmt/blob/main/doc/get-started.md): package manager installation, CMake FetchContent integration, and building from source using the top-level [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt).

## Installation Methods for fmtlib

### Using System Package Managers

The fastest way to install fmtlib depends on your platform. According to the official documentation in [`doc/get-started.md`](https://github.com/fmtlib/fmt/blob/main/doc/get-started.md), use the following commands for your environment:

- **Debian/Ubuntu**: `sudo apt install libfmt-dev`
- **macOS**: `brew install fmt`
- **Conda**: `conda install -c conda-forge fmt`
- **vcpkg**: `vcpkg install fmt`
- **Conan**: `conan install -r conancenter --requires="fmt/[*]" --build=missing`

These commands install the library system-wide, making the CMake targets available globally via `find_package(fmt)`.

### CMake FetchContent Integration

For projects already using CMake, FetchContent downloads fmtlib at configure time without requiring system installation. Add the following to your [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt):

```cmake
include(FetchContent)
FetchContent_Declare(
  fmt
  GIT_REPOSITORY https://github.com/fmtlib/fmt.git
  GIT_TAG 10.2.1  # Specify desired version

)
FetchContent_MakeAvailable(fmt)

target_link_libraries(your_target PRIVATE fmt::fmt)

```

This approach locks the fmtlib version to your project and avoids system dependency management.

### Building and Installing from Source

To compile fmtlib manually, clone the repository and use the standard CMake workflow defined in the root [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt):

```bash
git clone https://github.com/fmtlib/fmt.git
cd fmt
mkdir build && cd build
cmake ..                     # Add -DFMT_TEST=ON to build tests

make
sudo make install            # Optional: install system-wide

```

Key CMake options include `BUILD_SHARED_LIBS` (to build shared vs. static libraries), `CMAKE_POSITION_INDEPENDENT_CODE` (for position-independent code), and `FMT_TEST` (to enable the test suite).

## CMake Targets and Integration Modes

The root [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt) defines three distinct CMake targets that determine how fmtlib integrates with your project:

- **`fmt::fmt`**: The standard compiled library (static or shared depending on `BUILD_SHARED_LIBS`). Links against the implementation in `src/format.cc`.
- **`fmt::fmt-header-only`**: Header-only variant that processes [`include/fmt/format-inl.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h) directly at each translation unit without requiring a separate compilation step.
- **`fmt::fmt-module`**: C++20 module interface enabled with the `-DFMT_MODULE=ON` CMake option.

When using `fmt::fmt`, the linker resolves symbols against the compiled object code from `src/format.cc`, significantly reducing compilation times in large projects compared to the header-only approach.

## Header-Only vs. Compiled Library

fmtlib supports dual architectures. The **header-only mode** requires no linking step and includes the implementation via [`include/fmt/format-inl.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h), making it ideal for small projects or environments where building a separate library is impractical.

The **compiled library** mode (the default) processes `src/format.cc` once into a binary artifact that multiple translation units share. This is the recommended approach for production codebases as it minimizes compile times.

To use header-only mode without CMake targets, define the macro before including headers:

```cpp
#define FMT_HEADER_ONLY
#include <fmt/format.h>

```

## Usage Examples After Installation

Verify your fmtlib installation with a minimal program using [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) for basic printing:

```cpp
#include <fmt/core.h>

int main() {
    fmt::print("Hello, {}!\n", "world");
    return 0;
}

```

For advanced string formatting with positional arguments, use [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h):

```cpp
#include <fmt/format.h>

int main() {
    std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
    // s contains: "I'd rather be happy than right."
}

```

To format standard containers, include the ranges header located at [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h):

```cpp
#include <vector>
#include <fmt/ranges.h>

int main() {
    std::vector<int> v = {1, 2, 3};
    fmt::print("{}\n", v);  // Output: [1, 2, 3]
}

```

For C++20 modules (requires CMake `-DFMT_MODULE=ON`):

```cpp
import fmt;

int main() {
    fmt::print("Hello from a module!\n");
}

```

## Summary

- Install fmtlib using system package managers like `apt`, `brew`, `vcpkg`, or `conda` for immediate system-wide availability.
- Use CMake FetchContent to automatically download fmtlib at configure time without external dependencies.
- Build from source using the standard CMake workflow in the repository root when you need custom build configurations or specific compiler flags.
- Link against `fmt::fmt` for production builds to leverage pre-compiled code from `src/format.cc`, or use `fmt::fmt-header-only` for simpler integration without library linking.
- Include [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) for basic printing, [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) for full formatting capabilities, and [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h) for container serialization support.

## Frequently Asked Questions

### What is the difference between fmt::fmt and fmt::fmt-header-only?

The `fmt::fmt` target links against the compiled library built from `src/format.cc`, which minimizes compile times by processing the implementation once. The `fmt::fmt-header-only` target includes the implementation directly from [`include/fmt/format-inl.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h) at every translation unit, eliminating the need for linking but increasing compilation overhead in larger projects.

### Can I use fmtlib without CMake?

Yes. While CMake is the recommended build system, you can install fmtlib via package managers or copy the headers from `include/fmt/` into your project. For true header-only usage, define `FMT_HEADER_ONLY` before including the headers and ensure [`include/fmt/format-inl.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h) is accessible to the compiler.

### How do I enable C++20 modules support in fmtlib?

Enable the module target by configuring CMake with `-DFMT_MODULE=ON`, then link against `fmt::fmt-module` instead of `fmt::fmt`. This exposes the library as a C++20 module that you can import using `import fmt;` rather than traditional `#include` directives.

### Where are the core fmtlib header files located?

The primary headers reside in `include/fmt/` within the repository: [`core.h`](https://github.com/fmtlib/fmt/blob/main/core.h) provides basic printing functions like `fmt::print()`, [`format.h`](https://github.com/fmtlib/fmt/blob/main/format.h) contains the main `fmt::format()` API, and [`format-inl.h`](https://github.com/fmtlib/fmt/blob/main/format-inl.h) holds the header-only implementation details referenced by the compiled library.