# What's New in Catch2 v3 Compared to v2: Key Changes and Migration Guide

> Explore Catch2 v3! Discover key changes from v2 including static library builds C++14 support and faster compiles. Get your migration guide now.

- Repository: [Catch Org/Catch2](https://github.com/catchorg/Catch2)
- Tags: migration-guide
- Published: 2026-07-30

---

**Catch2 v3 replaces the single-header distribution with a static-library build and modular headers, requires C++14, improves compilation speed by roughly 80%, and reorganizes matchers into the `Catch::Matchers` namespace.**

Catch2 v3 represents a major architectural redesign of the popular C++ testing framework, moving away from the header-only model that defined v2. According to the catchorg/Catch2 source code, this release prioritizes compilation performance and build-system integration while maintaining the expressive testing DSL developers expect. Understanding these structural changes is essential for teams planning to migrate existing test suites.

## Static Library Distribution Replaces Header-Only Model

The most significant architectural change in Catch2 v3 is the shift from a pure header-only library to a compiled static library. In [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt), the build system now defines two primary targets: `Catch2` (the core framework) and `Catch2WithMain` (which provides the `main()` function). This eliminates the massive compilation overhead incurred by including the entire framework in every translation unit.

When linking your test executable, you now target these CMake libraries directly:

```cmake
add_executable(my_tests test_main.cpp)
target_link_libraries(my_tests PRIVATE Catch2WithMain)

```

This approach reduces compile times by approximately 80% compared to v2, as the framework is built once rather than parsed repeatedly.

## Modular Header Structure

### Split Headers vs. Monolithic Include

Catch2 v3 abandons the monolithic `<catch2/catch.hpp>` header in favor of a granular, split-header layout. The catch-all header is now `<catch2/catch_all.hpp>`, but the recommended practice is to include only what you need, such as `<catch2/catch_test_macros.hpp>` for basic testing functionality.

Key individual headers include:

- [`include/catch2/catch_test_macros.hpp`](https://github.com/catchorg/Catch2/blob/main/include/catch2/catch_test_macros.hpp) – Core test macros like `TEST_CASE` and `SECTION`
- [`include/catch2/matchers/catch_matchers_all.hpp`](https://github.com/catchorg/Catch2/blob/main/include/catch2/matchers/catch_matchers_all.hpp) – Aggregates all matcher definitions
- [`include/catch2/generators/catch_generators_all.hpp`](https://github.com/catchorg/Catch2/blob/main/include/catch2/generators/catch_generators_all.hpp) – Pulls in all generator utilities

### Migration Example for Matchers and Generators

When using matchers, you must now include the specific headers and use the updated namespace:

```cpp
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>

TEST_CASE("String matching") {
    std::string s = "hello world";
    REQUIRE_THAT(s, Catch::Matchers::ContainsSubstring("world"));
}

```

Note that `Contains` has been renamed to `ContainsSubstring`, and all matchers now live under `Catch::Matchers` instead of nested internal namespaces.

For generators:

```cpp
#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators_all.hpp>

TEST_CASE("Parametrised test") {
    int x = GENERATE(1, 2, 3);
    REQUIRE(x > 0);
}

```

## Updated Language and Performance Requirements

Catch2 v3 raises the minimum C++ standard from C++11 to **C++14**, allowing the framework to utilize modern language features internally. This requirement is enforced in the CMake configuration and documented in [`docs/migrate-v2-to-v3.md`](https://github.com/catchorg/Catch2/blob/main/docs/migrate-v2-to-v3.md).

The combination of the static-library model and split headers yields dramatic performance improvements. According to the release notes in [`docs/release-notes.md`](https://github.com/catchorg/Catch2/blob/main/docs/release-notes.md), v3 reduces inclusion overhead by roughly 80% compared to v2's single-header approach.

## Breaking API Changes

### Matcher Namespace Reorganization

All matchers have been moved to the `Catch::Matchers` namespace, creating a cleaner, flatter hierarchy. Additionally, the string matcher previously named `Contains` is now called `ContainsSubstring` to clarify its behavior.

### Reporter Interface Overhaul

Custom reporters and listeners must adapt to new interfaces in v3. The event system and reporter APIs have been restructured, as detailed in the migration documentation. Projects implementing custom reporters will need to update their inheritance and method signatures to match the new interfaces.

## CMake Integration and Package Manager Support

The CMake configuration in v3 generates `catch2-config.cmake` from the new layout, providing imported targets that work seamlessly with `find_package(Catch2)`. This redesign makes the framework significantly more friendly to package managers like vcpkg and Conan, resolving distribution challenges inherent in the v2 single-header model.

## Backward Compatibility via Amalgamated Header

For teams that require a single-file distribution, Catch2 v3 provides [`extras/catch_amalgamated.hpp`](https://github.com/catchorg/Catch2/blob/main/extras/catch_amalgamated.hpp). This file combines the entire framework into one header for backward compatibility, though it sacrifices the compilation speed benefits of the modular approach.

```cpp
#include "catch_amalgamated.hpp"  // From extras/catch_amalgamated.hpp

```

## Summary

- **Static library build**: Catch2 v3 uses `Catch2` and `Catch2WithMain` CMake targets instead of header-only inclusion.
- **Modular headers**: Replace `<catch2/catch.hpp>` with specific headers like `<catch2/catch_test_macros.hpp>` or the aggregate `<catch2/catch_all.hpp>`.
- **C++14 requirement**: The minimum language standard increased from C++11 to C++14.
- **Performance gains**: Compilation speed improves by approximately 80% due to the static-library architecture.
- **Matcher changes**: All matchers reside in `Catch::Matchers`, and `Contains` is now `ContainsSubstring`.
- **Amalgamated option**: Use [`extras/catch_amalgamated.hpp`](https://github.com/catchorg/Catch2/blob/main/extras/catch_amalgamated.hpp) for single-file compatibility.

## Frequently Asked Questions

### Is Catch2 v3 backward compatible with v2?

No, v3 introduces breaking changes that require code modifications. You must update include paths, matcher namespaces, and CMake targets. However, the testing macros (`TEST_CASE`, `REQUIRE`, etc.) remain syntactically identical, minimizing changes to actual test logic.

### Do I need to change all my includes when migrating to v3?

Yes. The monolithic `<catch2/catch.hpp>` is removed in v3. You should include `<catch2/catch_test_macros.hpp>` for basic functionality, or `<catch2/catch_all.hpp>` for the convenience of a single include. Matchers and generators require their specific "all" headers or individual component headers.

### Why did Catch2 switch from header-only to a static library?

The header-only model in v2 caused excessive compilation times because the entire framework was parsed in every translation unit. By compiling Catch2 as a static library defined in [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt), v3 reduces build overhead by roughly 80% while maintaining the same runtime behavior and API expressiveness.

### Can I still use Catch2 v3 as a single-header library?

Yes, though it is not recommended for new projects. The file [`extras/catch_amalgamated.hpp`](https://github.com/catchorg/Catch2/blob/main/extras/catch_amalgamated.hpp) provides a single-header distribution for backward compatibility, but you lose the compilation speed benefits of the modular, static-library approach.