# How fmtlib Implements C++20 std::format and C++23 std::print Support

> Discover how fmtlib implements C++20 std::format and C++23 std::print. Learn about its high-performance output buffering and compile-time format string validation for efficient C++ formatting.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: internals
- Published: 2026-09-11

---

**fmtlib serves as the reference implementation for C++20 std::format and C++23 std::print, exposing these standard interfaces through [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) and [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) while providing high-performance output buffering and compile-time format string validation.**

The fmtlib/fmt repository forms the foundation of modern C++ text formatting as the direct predecessor to the C++20 `<format>` and C++23 `<print>` standard library headers. Understanding how fmtlib supports C++20 std::format and C++23 std::print reveals the architectural decisions that enable sub-second formatting of millions of records without iostream overhead.

## Architecture of C++20 std::format Implementation

fmtlib defines the API that standardized into C++20 std::format, implementing the **format string syntax** and **argument handling** that became the international standard.

### The format() Function Template

In [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), the primary entry point `fmt::format()` provides the same interface as `std::format()`:

```cpp
template <typename... Args>
FMT_INLINE auto format(format_string<Args...> fmt, Args&&... args) -> std::string {
  return vformat(fmt, fmt::make_format_args(args...));
}

```

This implementation delegates to **type-erased formatting** via `vformat()` defined in the same header, minimizing binary bloat while preserving type safety through the `format_string` concept-like constraint.

### Compile-Time Format String Validation

fmtlib supports C++20 `consteval` format string parsing through mechanisms in [`include/fmt/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h). The library parses format specifiers at compile time when possible, validating argument types against format string placeholders before runtime using the `FMT_COMPILE` macro.

## C++23 std::print Implementation in fmtlib

The C++23 `std::print` functionality draws directly from fmtlib's existing `fmt::print` implementation, which has supported direct stdout output since version 5.0.

### High-Performance Output Buffering

In [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h), `fmt::print()` avoids iostreams entirely and delegates to `vprint()`:

```cpp
template <typename... Args>
FMT_INLINE void print(format_string<Args...> fmt, Args&&... args) {
  return detail::is_utf8() ? vprint(std::stdout, fmt, fmt::make_format_args(args...))
                           : vprint(std::stdout, fmt, fmt::make_format_args(args...));
}

```

The actual output buffering occurs in `src/format.cc`, where `vprint()` uses `std::fwrite()` for block writes rather than character-by-character output, achieving **5-10x faster** performance than `std::ostream`.

### Unicode and Locale Handling

fmtlib's print support handles UTF-8 validation through `detail::is_utf8()` checks in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), ensuring correct behavior for multibyte characters without relying on global C++ locales.

## Type Erasure and Argument Storage

At the heart of both std::format and std::print compatibility lies fmtlib's **dynamic argument store**. The `format_args` type alias in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) implements the type erasure required by the C++20 standard:

```cpp
// From include/fmt/core.h
using format_args = basic_format_args<format_context>;

```

This type erasure allows `vformat()` and `vprint()` to process arguments without template instantiation for every unique parameter combination, reducing compile times and binary size while maintaining the static type safety of the outer API.

## Integration with Standard Library Features

While fmtlib predates standardization, it detects standard library availability through `__cpp_lib_format`. In [`include/fmt/std.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/std.h), the library provides formatters for standard types like `std::optional`, `std::variant`, and `std::thread::id`, ensuring feature parity with C++23 standard library extensions.

When compiled with C++20 or later, fmtlib remains fully compatible with `std::format` output iterators and `std::format_to_n` algorithms, allowing seamless interoperability between `fmt::format` and `std::format` in the same codebase.

## Summary

- **fmtlib originates std::format**: The C++20 `<format>` header standardizes the API first implemented in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) with function templates like `fmt::format()` and `fmt::vformat()`.
- **C++23 print performance**: fmtlib's `fmt::print()` in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) uses `std::fwrite()` buffering via `vprint()` in `src/format.cc`, delivering the high-performance output that became C++23 `std::print`.
- **Type erasure architecture**: Both standards rely on fmtlib's `format_args` type erasure pattern to minimize template bloat while preserving compile-time format string validation.
- **Cross-version compatibility**: Headers like [`include/fmt/std.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/std.h) extend support to standard library types, maintaining API consistency across C++17, C++20, and C++23 compilation modes.

## Frequently Asked Questions

### Does fmtlib provide std::format in the std namespace?

No, fmtlib implements `fmt::format` in its own namespace as the reference implementation. Standard library vendors provide `std::format` by adopting fmtlib's interface. You should include `<fmt/format.h>` and use `fmt::format` directly, which remains compatible with the standard specification and works on pre-C++20 compilers.

### How does fmt::print differ from C++23 std::print?

**`fmt::print`** has been available since fmtlib 5.0 and implements the same formatting specification as C++23 `std::print`. The primary difference is namespace placement—`fmt::print` resides in the `fmt` namespace and supports older C++ standards, whereas `std::print` requires C++23. Both use the same efficient buffering strategy via `vprint()` in `src/format.cc`.

### Can I migrate from fmtlib to standard library format incrementally?

Yes, fmtlib maintains API compatibility with C++20 std::format. You can replace `fmt::format` with `std::format` calls incrementally, as both support the same format string syntax and argument handling. However, fmtlib offers additional features like named arguments and compile-time format compilation that remain unavailable in standard C++ through C++23.

### Why use fmtlib instead of native C++23 std::print?

fmtlib provides broader compiler support (C++11 and later) and additional features like runtime format string compilation via `FMT_COMPILE` macros, color output via `fmt::print` with text styling, and Windows console UTF-8 handling. The library also typically delivers faster compile times than standard library `<format>` headers on older compilers while maintaining binary compatibility through `src/format.cc`.