A modern formatting library
2026-09-04 12:13:45 -07:00
.github Bump msys2/setup-msys2 from 2.28.0 to 2.32.0 (#4908) 2026-09-01 10:51:53 -07:00
doc Move migration guidance to documentation 2026-09-04 09:37:28 -07:00
include/fmt Fix debug format width calculation (#4902) 2026-09-04 09:17:58 -07:00
src Format enums annotated with fmt::as_identifiers (requires C++26 reflection) (#4885) 2026-08-23 09:31:28 -07:00
support Format enums annotated with fmt::as_identifiers (requires C++26 reflection) (#4885) 2026-08-23 09:31:28 -07:00
test Fix debug format width calculation (#4902) 2026-09-04 09:17:58 -07:00
.clang-format Update and apply clang-format 2025-05-03 07:29:31 -07:00
.clang-tidy Add .clang-tidy 2025-09-03 11:05:49 -07:00
.cmake-format Rename cmake-format config 2026-03-05 17:36:49 -08:00
.gitignore Add .gradle directory to .gitignore (#4799) 2026-06-09 06:03:37 -07:00
ChangeLog.md Document C++20 module usage with CMake (#4891) 2026-08-30 10:17:00 -07:00
CMakeLists.txt Stop enabling C++26 reflection by default 2026-08-29 16:28:09 -07:00
CONTRIBUTING.md Undo the move because the doc is not a GH template 2021-08-06 11:22:33 -07:00
LICENSE Split exception into a separate file not to confuse openssf 2025-12-17 10:31:12 -08:00
README.md Update compile-time benchmark results 2026-09-04 12:13:45 -07:00

{fmt}

image image image fmt is continuously fuzzed at oss-fuzz OpenSSF Best Practices image Ask questions at StackOverflow with the tag fmt Support Ukraine

{fmt} is an open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.

Documentation

Cheat Sheets

Q&A: ask questions on StackOverflow with the tag fmt.

Try {fmt} in Compiler Explorer.

Live demo by Demoshell

Features

  • Simple format API with positional arguments for localization
  • Implementation of C++20 std::format and C++23 std::print
  • Format string syntax similar to Python's format
  • Fast IEEE 754 floating-point formatter with correct rounding, shortness and round-trip guarantees using the Dragonbox algorithm
  • Portable Unicode support
  • Safe printf implementation including the POSIX extension for positional arguments
  • Extensibility: support for user-defined types
  • High performance: faster than common standard library implementations of (s)printf, iostreams, to_string and to_chars, see Speed tests and Converting a hundred million integers to strings per second
  • Small code size both in terms of source code with the minimum configuration consisting of just three files, base.h, format.h and format-inl.h, and compiled code; see Compile time and code bloat
  • Reliability: the library has an extensive set of tests and is continuously fuzzed
  • Safety: the library is fully type-safe, errors in format strings can be reported at compile time, automatic memory management prevents buffer overflow errors
  • Ease of use: small self-contained code base, no external dependencies, permissive MIT license
  • Portability with consistent output across platforms and support for older compilers
  • Clean warning-free codebase even on high warning levels such as -Wall -Wextra -pedantic
  • Locale independence by default
  • Optional header-only configuration enabled with the FMT_HEADER_ONLY macro

See the documentation for more details.

Examples

Print to stdout (run)

#include <fmt/base.h>

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

Format a string (run)

std::string s = fmt::format("The answer is {}.", 42);
// s == "The answer is 42."

Format a string using positional arguments (run)

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

Print dates and times (run)

#include <fmt/chrono.h>

int main() {
  auto now = std::chrono::system_clock::now();
  fmt::print("Date and time: {}\n", now);
  fmt::print("Time: {:%H:%M}\n", now);
}

Output:

Date and time: 2023-12-26 19:10:31.557195597
Time: 19:10

Print a container (run)

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

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

Output:

[1, 2, 3]

Check a format string at compile time

std::string s = fmt::format("{:d}", "I am not a number");

This gives a compile-time error in C++20 because d is an invalid format specifier for a string.

Write a file from a single thread

#include <fmt/os.h>

int main() {
  auto out = fmt::output_file("guide.txt");
  out.print("Don't {}", "Panic");
}

This can be up to 9 times faster than fprintf.

Print with colors and text styles

#include <fmt/color.h>

int main() {
  fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
             "Hello, {}!\n", "world");
  fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
             fmt::emphasis::underline, "Olá, {}!\n", "Mundo");
  fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "你好{}\n", "世界");
}

Output on a modern terminal with Unicode support:

image

Benchmarks

Speed tests

Library Method Run Time, s
libc printf 0.66
libc++ std::ostream 1.63
{fmt} 12.1 fmt::print 0.44
Boost Format 1.88 boost::format 3.89
Folly Format folly::format 1.28

{fmt} is the fastest of the benchmarked methods, ~50% faster than printf.

The above results were generated by building tinyformat_test.cpp on macOS 15.6.1 with clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT, and taking the best of three runs. In the test, the format string "%0.10f:%04d:%+g:%s:%p:%c:%%\n" or equivalent is filled 2,000,000 times with output sent to /dev/null; for further details refer to the source.

{fmt} is up to 20-30x faster than std::ostringstream and sprintf on IEEE754 float and double formatting (dtoa-benchmark) and faster than double-conversion and ryu:

image

Compile time and code bloat

The script bloat-test.py from format-benchmark tests compile time and code bloat for nontrivial projects. It generates 100 translation units and uses printf() or its alternative five times in each to simulate a medium-sized project. The resulting executable size and compile time on an Apple M5 Max running macOS 26.6.2 with Apple Clang 21.0.0 (clang-2100.1.1.101), taking the best of three runs, are shown in the following tables.

Optimized build (-O3)

Method Compile Time, s Executable size, KiB Stripped size, KiB
printf 1.2 54 50
IOStreams 21.8 98 84
{fmt} 12.2 4.2 54 50
tinyformat 25.5 164 136
Boost Format 1.88 43.4 550 333
stb_sprintf 1.4 87 83

{fmt} is fast to compile and is comparable to printf in terms of per-call binary size (within a rounding error on this system).

Non-optimized build

Method Compile Time, s Executable size, KiB Stripped size, KiB
printf 1.1 54 50
IOStreams 20.7 88 68
{fmt} 12.2 4.0 87 84
tinyformat 21.8 188 145
Boost Format 1.88 30.0 749 430
stb_sprintf 1.2 103 99

libc, libc++, and libfmt were linked as shared libraries to compare formatting function overhead only. tinyformat, Boost Format, and stb_sprintf are header-only libraries.

Projects using {fmt}

Notable users include:

Find more projects using {fmt} on GitHub.