# Vulkan-Hpp: generated C++ bindings that hide the C API without costing anything

> Khronos Group's header-only C++ layer over Vulkan, machine generated from the same XML the C headers come from, with type safe enums, RAII handles and an unusually honest breaking changes list.

**KhronosGroup/Vulkan-Hpp** — Open-Source Vulkan C++ API

- Repository: https://github.com/KhronosGroup/Vulkan-Hpp
- Stars: 3,795 · Forks: 374
- Language: C++
- License: Apache-2.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/khronosgroup-vulkan-hpp

## Generated from the same XML as the C headers

The most important architectural fact is stated in the second paragraph of the README. This repository contains the generators for Vulkan-Hpp, which accept the XML specification of Vulkan and emit the C++ bindings. The header you include is output, not something anyone typed.

That has a direct consequence for how you should relate to breaking changes. The binding follows the C API, so anything the spec adds or renames shows up in the C++ layer, sometimes with a different signature because C++ can express what C cannot. It also means the bindings are exactly as current as the XML the generator was last run against, and the project publishes a breaking changes list precisely so that the difference between two versions is documented rather than discovered at compile time.

The value proposition is stated with a constraint that deserves attention: header-only C++ bindings to improve the developer experience with Vulkan without introducing run-time CPU costs. The no-overhead clause is what distinguishes this from a wrapper library that adds a layer of indirection. Nothing here is a virtual dispatch or a copy that would not otherwise happen.

It is Apache-2.0 licensed, written in C++, has 3,795 stars and 374 forks, and was last pushed on 2026-09-23.

## Four things the binding adds over the C API

The feature list is short enough to be credible: type safety for enumerations and bit-fields, STL container support, exception support, and several varieties of RAII-capable types.

Type safety for enumerations and bit-fields is the one that pays off fastest. In C, passing an integer where an enum is expected is legal and produces a confusing failure far from the call site. In the binding, an enumeration value is its own type, and a bit-field mask is constructed from named values rather than shifted integers. Combined with the STL container support, the result is that function signatures express intent rather than encoding it in comments.

Exceptions are an add, not a change. The C API returns `VkResult` codes, and the binding keeps that but offers a mode where a failure throws instead of requiring you to check every call.

RAII is where the design work is, and it is the subject of a dedicated documentation page. `docs/Handles.md` describes three families of handle types providing semantics similar to `std::unique_ptr` and `std::shared_ptr`, plus `vk::raii` types. Choosing between them is the main architectural decision a project makes when adopting this binding, and the README is careful to present it as a choice rather than a default.

## Getting it installed without building anything

The recommended route is not this repository. Vulkan-Hpp has shipped with the LunarG Vulkan SDK since version 1.0.24, and the README states plainly that this remains the recommended installation method. If you need something newer than your SDK ships, the fallback is the Khronos Vulkan-Headers repository.

Both package managers also carry it, in a port named `vulkan-headers` rather than `vulkan-hpp`, which is worth knowing before you go looking for a package that does not appear to exist:

```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install vulkan-headers
```

Conan has an equivalent `vulkan-headers` recipe. The README is careful about credit here, noting that the vcpkg and Conan packages are kept up to date by Microsoft and community members, and that requests for those should go to their repositories rather than here.

That division of responsibility is the healthy pattern. If you are reading the Vulkan-Hpp repository to file an issue about a vcpkg version, you are in the wrong place, and the README tells you so before you waste the effort.

## The breaking changes list is worth reading before you pin a version

The project states it tries to keep the API constant or backwards compatible across all flavours of Vulkan-Hpp, with unavoidable breaking changes usually introduced to fix bugs. Then it publishes every one of them by version, which is more transparency than most binding projects offer.

Five are listed. In v1.4.357, the fourth argument to the device level dispatcher init, `vkGetDeviceProcAddr`, changed from optional to required, for a function usually called through `VULKAN_HPP_DEFAULT_DISPATCHER.init( instance, vkGetInstanceProcAddr, device, vkGetDeviceProcAddr )`. In v1.4.351, functions taking a C-array of values changed to take a `std::array` instead, for argument safety, affecting `vk::CommandBuffer::setFragmentShadingRateKHR` and three `vk::raii` equivalents.

The remaining three are module-level. The `vulkan_hpp` C++ named module was renamed to `vulkan` in v1.4.334. `import std` became mandatory when using the named module in v1.4.329. And in v1.4.324, the return type of `vk::raii::Device::acquireNextImage2KHR` and `vk::raii::SwapchainKHR::acquireNextImage` changed from a `std::pair` to `vk::ResultValue<uint32_t>`.

Two observations. The C++20 named module story is still settling, which is normal for an ecosystem feature this new. And the current version is v1.4.363, released 2026-09-21, with release notes dominated by generator work and cleanups rather than API changes.

## The samples directory explains the API by build-up

There are two sample trees and they serve different purposes.

The numbered series is a progression: `01_InitInstance`, `02_EnumerateDevices`, `03_InitDevice`, `04_InitCommandBuffer`, `05_InitSwapchain`, `06_InitDepthBuffer`, `07_InitUniformBuffer`, `08_InitPipelineLayout`, `09_InitDescriptorSet`, `10_InitRenderPass`, `11_InitShaders`, `12_InitFrameBuffers`, `13_InitVertexBuffer`, `14_InitPipeline`, `15_DrawCube`, and then `16_Vulkan_1_1`. Each step adds one concept to a working program, which makes it a genuine teaching sequence rather than a set of unrelated demos. The cost is that you read fifteen directories to reach a triangle.

The topic samples drop that constraint: `CopyBlitImage`, `CreateDebugUtilsMessenger`, `DebugUtilsObjectName`, `DrawTexturedCube`, `DynamicUniform`, `EnableValidationWithCallback`, `EnumerateDevicesAdvanced` and `Events`. These answer one question each. `EnableValidationWithCallback` in particular is the one to find first, because running Vulkan without validation layers while developing is how people lose days.

There is also a `RAII_Samples/` directory, which is the fastest way to understand what the RAII handle families change in practice.

The repository vendors its dependencies as submodules: `Vulkan-Headers`, `glfw`, `glm`, `glslang`, `tinyxml2`, plus `CMakeLists.txt` and `CMakePresets.json`. The README links two external projects worth knowing about: a port of Sascha Willems's Vulkan examples to Vulkan-Hpp, and Vookoo, a set of stateful helper classes, which has an introduction article in the ACCU Overload journal.

## A compiler matrix that says what the bindings actually support

The CI section publishes the full runner matrix rather than a badge, which is more information than a badge would give you. Testing covers Windows 2022 and 2025, Ubuntu 22.04 and 24.04, and macOS 14, 15 and 26.

On Windows the coverage is Clang 17 and 18 plus VS 2022 and VS 18, with no GCC. On Ubuntu 22.04 it is GCC 10, 11 and Clang 13, 14, 15; on 24.04 it extends to GCC 12, 13, 14 and Clang 16, 17, 18. On macOS it is Clang only, at 15, 17 and 17. The `.github/workflows/build.yml` file governs all of it.

Two things follow. First, if you are on an older GCC than 10 you are outside the tested range, which for a binding library matters more than it would for an application. Second, macOS coverage runs through MoltenVK rather than a native Vulkan driver, so a macOS-only problem is more likely to be a MoltenVK issue than a binding one.

There is also a `VulkanHpp.natvis` file in the tree, which is the Visual Studio debugger visualisation file. That is a small detail that tells you someone cared about what the handles look like in a debugger rather than only about whether they compile.

The README ends with a formatting requirement for contributors: clang-format version 23.1.0 for the generated files. Version 1.4.362 added support for clang-format 23, and 1.4.361 introduced the use of concepts for C++20 and above. The bindings are tracking the language as well as the API.

## Conclusion

Vulkan-Hpp removes the parts of Vulkan that C programmers tolerate and C++ programmers should not, and it does so without a runtime cost, which is why the argument against it is rarely technical. What you accept is a generated layer that tracks the C API rather than an independent one, so a spec change shows up as a binding change. The repository is explicit about that, publishing breaking changes with the version that introduced them. Start by taking Vulkan-Hpp from the LunarG SDK, and read docs/Usage.md and docs/Handles.md before deciding which handle family you want.

## FAQ

### Is Vulkan C++ or C?

The Vulkan API itself is a C API, and Vulkan-Hpp is a generated C++ binding over it. The C headers come from the XML specification and the C++ headers come from the same XML, which is why the two track each other closely and why breaking changes in the binding are published by version.

### What is an HPP file in C++?

In this project the .hpp files are generated C++ headers, produced by the generator in this repository from the Vulkan XML specification rather than written by hand. Vulkan-Hpp is header-only, so including the generated header is the whole integration step.

### Does using Vulkan-Hpp add runtime overhead?

The project states the goal explicitly as improving the developer experience without introducing run-time CPU costs. That is the reason for the header-only design and for generating from the spec rather than hand-writing a wrapper with virtual dispatch.

### How do I install Vulkan-Hpp?

Take it from the LunarG Vulkan SDK, where it has shipped since 1.0.24, which is the recommended route. For something newer, use the Vulkan-Headers repository, the vulkan-headers port in vcpkg, or the equivalent Conan recipe.

### What are the RAII handle families in Vulkan-Hpp?

Three: handles with semantics like std::unique_ptr, handles with semantics like std::shared_ptr, and the vk::raii types, which offer object-oriented semantics and are described as RAII handles. docs/Handles.md is the page that walks through the differences.

### Is Vulkan-Hpp better than OpenGL for performance?

That question is about Vulkan against OpenGL rather than about this binding, and the binding does not change the answer. What Vulkan-Hpp does is make Vulkan more pleasant to write by adding type safety for enums and bit-fields, STL containers, exceptions and RAII handles without adding runtime cost.

## Sources

- [Issues](https://github.com/KhronosGroup/Vulkan-Hpp/issues)
- [KhronosGroup/Vulkan-Hpp on GitHub](https://github.com/KhronosGroup/Vulkan-Hpp)
- [License: Apache-2.0](https://github.com/KhronosGroup/Vulkan-Hpp/blob/main/LICENSE)
- [README](https://github.com/KhronosGroup/Vulkan-Hpp/blob/main/README.md)
- [Releases](https://github.com/KhronosGroup/Vulkan-Hpp/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/khronosgroup-vulkan-hpp
