This repository is a template, not a finished library. It is a 2026-grade, batteries-included starting point for a modern C++ library. The only "feature" it ships is a trivial
sum()— its real value is the infrastructure around it. Clone it, renamemylib, delete the toy code, and start building. See Using this template below.
A complete, opinionated, 2026 modern C++ project skeleton:
| Area | What's included |
|---|---|
| Language | C++26 (cxx_std_26), classic headers (modules deliberately avoided for portability) |
| TDD-first | Catch2 v3 wired to CTest; the workflow and tooling are built around failing test → implementation |
| Build | Modern target-based CMake (3.28+), CMakePresets.json, namespaced mylib::mylib, full install/export so consumers find_package(mylib) |
| Dependencies | vcpkg manifest mode (vcpkg.json, pinned baseline) — with a transparent FetchContent fallback so it builds without vcpkg too |
| One front door | A self-documenting Makefile (make help) wraps every common task |
| Quality gates | clang-format, clang-tidy, pre-commit hooks, compiler warnings-as-errors |
| Sanitizers | ASan + UBSan and TSan presets/targets |
| Coverage | make coverage → inspectable HTML + lcov; Codecov upload in CI |
| CI / CD | GitHub Actions matrix across Linux x86_64/arm64, macOS arm64, Windows x64; CodeQL (build-free); Doxygen → GitHub Pages; release-please |
| Unified docs | One Sphinx site documenting both the C++ API (via Breathe/Doxygen) and the Python API (via autodoc), auto-deployed to Pages |
| First-class Python | Integral nanobind bindings (ON by default) with their own full pipeline — pytest, ruff, mypy --strict, coverage, type stubs, uv-driven, dedicated CI + cibuildwheel — see python-compatibility.md |
| Combined coverage | C++ (llvm-cov) and Python (coverage.py) reported together in one repo via Codecov flags (cpp / python) |
| Consumer-tested | A standalone/ example built against the installed package, verified in CI (validates find_package/install) |
| IDE-agnostic | Works identically in Neovim, VSCode, CLion, … via compile_commands.json + clangd (see CONTRIBUTING) |
| Agent-ready | AGENTS.md (+ CLAUDE.md), ADRs, and design docs (coding standards, TDD, dependencies, Python) so LLM coding agents extend the code correctly and safely |
make test # configure + build + run the full test suite (the TDD loop)
make help # see every available taskvcpkg:
vcpkg install mylib # once published to a registryCMake FetchContent:
include(FetchContent)
FetchContent_Declare(mylib
GIT_REPOSITORY https://github.com/bvdmitri/cpp-python-template-2026.git
GIT_TAG v0.1.0)
FetchContent_MakeAvailable(mylib)
target_link_libraries(your_app PRIVATE mylib::mylib)After cmake --install:
find_package(mylib CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE mylib::mylib)#include <mylib/mylib.hpp>
#include <print>
int main() { std::println("{}", mylib::sum(2, 3)); } // 5After cloning, do the following to turn it into your real library:
- Rename the placeholder
mylib. It is the single token used for the namespace, the CMake target/alias (mylib::mylib), the package, theinclude/mylib/directory, theMYLIB_*macros/options, and doc strings. Pick a name and find-replace it everywhere, then rename the directory:(The Python extension module nameNEW=yourlib # Replace contents everywhere (use `sed -i` without '' on GNU/Linux): grep -rl --exclude-dir=out --exclude-dir=.git 'mylib\|MYLIB' . \ | xargs sed -i '' "s/mylib/$NEW/g; s/MYLIB/$(echo $NEW | tr a-z A-Z)/g" # macOS sed # Rename the name-bearing files/dirs (contents are already replaced above): git mv include/mylib include/$NEW git mv include/$NEW/mylib.hpp include/$NEW/$NEW.hpp git mv bindings/python/mylib bindings/python/$NEW # Python package dir
mylib_extand thepyproject.tomlpackage name are updated by the content replace above.) Then runmake test— it should still be green (this is exercised by the rename-sanity check in CONTRIBUTING/verification). - Update project metadata:
project(... VERSION ...)inCMakeLists.txt, thename/version/homepage/descriptioninvcpkg.json, and the GitHub URLs (currentlybvdmitri/cpp-python-template-2026) in this README,vcpkg.json, badges, and workflows. - Set the copyright holder in
LICENSE(or swap MIT for another license). - Replace the toy API: delete
sum.{hpp,cpp}andsum_test.cpp; add your own headers underinclude/<name>/, sources undersrc/, tests undertest/(write the failing test first — see AGENTS.md). - Declare real dependencies in
vcpkg.jsonand re-discover them incmake/package-config.cmake.inviafind_dependency(...)(this file is named generically, so renaming the project only touches its contents, not its name). - Fill in
docs/design/architecture-overview.mdand add ADRs as you make decisions; tailordocs/design/coding-standards.mdto your project. - When ready to publish (and only then): create the GitHub repo, push, enable GitHub Pages + Codecov, turn on branch protection (require the CI test jobs), and optionally mark the repo a template under repo Settings.
Bindings are an integral part of the template (ON by default for a top-level
build) with their own full quality pipeline. With uv:
make py-check # ruff + mypy --strict + pytest (the Python gate)
make python-test # just the pytest suite
make py-coverage # tests + coverage (HTML + xml)
make wheel # build a wheel (scikit-build-core)
make check # run BOTH the C++ and Python pipelinesimport mylib
mylib.sum(2, 3) # 5
mylib.__version__ # "0.1.0"See docs/design/python-compatibility.md for the binding-friendly API rules and how to expose more of the library.
- Unified docs site — C++ and Python API in one Sphinx site (auto-deployed); build locally with
make docs - Contributing & IDE setup — Neovim / VSCode / CLion +
uv - Coding standards — stable, fast, safe modern C++
- Test-driven development
- Dependency management — add/remove deps
- Python compatibility
- Architecture & ADRs
- Agent guide
A C++26-capable compiler (GCC 16+, Clang 18+, MSVC 19.4x+), CMake ≥ 3.28, and
Ninja. vcpkg is optional. GNU Make is used for the task runner (Windows: use
WSL/Git-Bash, or call the cmake --preset commands directly). For the optional
Python bindings, uv provides the interpreter and
build tooling.
MIT.