# How to Achieve Colored Output Using fmtlib: A Complete Guide to ANSI Styling

> Learn how to achieve colored output with fmtlib using text_style, fg, bg, and emphasis flags. This guide shows you how to use fmt::print for stunning ANSI styling.

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

---

**Use `fmt::print` with `text_style` objects constructed via `fg()`, `bg()`, and `emphasis` flags combined with the `|` operator.**

The {fmt} library provides a built-in, header-only API for ANSI-styled terminal output through [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h). This implementation generates escape sequences at compile time with zero runtime overhead beyond the actual terminal writes.

## Understanding the Color System Architecture

The coloring capability in fmtlib centers on three core enumerations and a composable style class.

### Color Definitions: `enum class color`

The `color` enumeration in [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h) defines 256 RGB color values accessible by name:

```cpp
// Lines 16-38: Named RGB colors
enum class color : uint32_t {
  alice_blue = 0xF0F8FF,       // rgb(240,248,255)
  antique_white = 0xFAEBD7,    // rgb(250,235,215)
  crimson = 0xDC143C,          // rgb(220,20,60)
  // ... 250+ additional named colors
};

```

These values store raw 24-bit RGB integers. The implementation extracts red, green, and blue components to generate `\x1b[38;2;<r>;<g>;<b>m` foreground sequences or `\x1b[48;2;<r>;<g>;<b>m` for backgrounds.

### Terminal Colors: `enum class terminal_color`

For compatibility with limited terminals, [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h) provides standard 8/16 color palette mappings:

```cpp
// Lines 60-77: Standard ANSI terminal colors
enum class terminal_color : uint8_t {
  black = 0,
  red,
  green,
  yellow,
  blue,
  magenta,
  cyan,
  white,
  bright_black = 8,
  bright_red,
  // ... through bright_white
};

```

These map to escape codes `\x1b[30m` through `\x1b[37m` and `\x1b[90m` through `\x1b[97m` for bright variants.

### Text Emphasis: `enum class emphasis`

Style attributes beyond color live in the `emphasis` enumeration:

```cpp
// Lines 79-88: Style flags
enum class emphasis : uint8_t {
  bold = 1,
  italic = 1 << 1,
  underline = 1 << 2,
  strikethrough = 1 << 3
};

```

These are bitwise flags, enabling combination through `|`.

## Composing Styles with `text_style`

The `text_style` class packs foreground, background, and emphasis into a 64-bit value. Located in [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h) (lines 35-70), it exposes three key composition functions:

- **`fg(color)`** or **`fg(terminal_color)`** — sets foreground color
- **`bg(color)`** or **`bg(terminal_color)`** — sets background color  
- **Emphasis flags** — passed directly and combined with `|`

The `operator|` implementation safely merges styles, rejecting incompatible `terminal_color` foreground/background combinations that would produce invalid escape sequences.

### Internal Escape Sequence Generation

Helper functions in [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h) (lines 46-64) convert style specifications to ANSI:

```cpp
// Simplified view of internal mechanism
namespace detail {
  constexpr void make_foreground_color(memory_buffer& buf, color c);
  constexpr void make_background_color(memory_buffer& buf, color c);
  constexpr void make_emphasis(memory_buffer& buf, emphasis em);
}

```

All generation is `constexpr` — escape codes compute at compile time when possible.

## Printing with Colored Output

Overloads of `fmt::print` and `fmt::println` in [`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h) (lines 97-125) accept `text_style` as their first argument. The implementation:

1. Creates a temporary buffer
2. Writes opening escape sequences for the style
3. Invokes `detail::vformat_to` to format the payload
4. Appends reset code `\x1b[0m` if the style changed

This automatic reset ensures subsequent output returns to default terminal styling.

## Practical Code Examples

### Basic Colored Error Message

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

int main() {
    fmt::print(
        fmt::emphasis::bold | fmt::fg(fmt::color::red),
        "Error: {}\n", "file not found");
}

```

Output: Bold red "Error:" with plain argument text, then implicit reset.

### Complex Style Composition

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

int main() {
    fmt::println(
        fmt::emphasis::underline | fmt::emphasis::italic |
        fmt::fg(fmt::color::green) | fmt::bg(fmt::color::steel_blue),
        "Success: {} items processed", 42);
}

```

Multiple emphases and full RGB foreground/background combination via chained `|` operators.

### Terminal Palette for Portability

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

int main() {
    fmt::print(
        fmt::emphasis::bold | fmt::fg(fmt::terminal_color::bright_yellow),
        "Warning: low disk space\n");
}

```

Use `terminal_color` when targeting terminals with limited color support.

## Header-Only Usage

All colored output functionality requires a single include:

```cpp
#define FMT_HEADER_ONLY  // Optional: forces header-only mode
#include <fmt/color.h>

```

No library linking required when `FMT_HEADER_ONLY` is defined. The entire color system resolves at compile time.

## Summary

- **[`include/fmt/color.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/color.h)** contains all colored output declarations: `color`, `terminal_color`, `emphasis`, `text_style`, and style-aware `fmt::print` overloads
- **Style composition** uses `fg()`, `bg()`, emphasis flags, and `|` operator
- **Escape generation** is `constexpr` with zero runtime overhead beyond I/O
- **Automatic reset** (`\x1b[0m`) ensures clean terminal state after each styled print
- **Both RGB and terminal palettes** supported for broad compatibility

## Frequently Asked Questions

### Does fmtlib colored output work on Windows?

Yes. {fmt} automatically detects Windows terminals and uses appropriate console APIs when standard ANSI escape sequences aren't supported. The public API remains identical — `text_style` objects work transparently across platforms.

### Can I store and reuse styled formats?

Absolutely. `text_style` is a lightweight value type (64 bits). Store composed styles in variables:

```cpp
const auto error_style = fmt::emphasis::bold | fmt::fg(fmt::color::red);
fmt::print(error_style, "First error\n");
fmt::print(error_style, "Second error\n");

```

### How do I disable colors at runtime?

The {fmt} API doesn't provide runtime toggles directly. Implement a wrapper:

```cpp
void conditional_print(bool use_color, fmt::text_style style, 
                       fmt::string_view fmt, auto&&... args) {
    if (use_color) {
        fmt::print(style, fmt, std::forward<decltype(args)>(args)...);
    } else {
        fmt::print(fmt, std::forward<decltype(args)>(args)...);
    }
}

```

Check environment variables like `NO_COLOR` or terminal capability before calling.

### Are 256-color terminal codes supported?

The `color` enum provides 24-bit RGB values. Terminals supporting 256 colors receive approximate mappings; true-color terminals display exact RGB. For strict 256-color palette control, map RGB values to the 6×6×6 color cube manually or use `terminal_color` for guaranteed basic support.