# OpenXR-SDK-Source: the loader, API layer samples and validation layers in one tree

> The Khronos source repository for the OpenXR loader, validation layers and sample code, aimed at people who need to build or modify the runtime itself rather than just link against it.

**KhronosGroup/OpenXR-SDK-Source** — Sources for OpenXR loader, basic API layers, and example code.

- Repository: https://github.com/KhronosGroup/OpenXR-SDK-Source
- Website: https://khronos.org/openxr
- Stars: 836 · Forks: 308
- Language: Python
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/khronosgroup-openxr-sdk-source

## Two Khronos trees, one for runtimes and one for applications

The first thing to understand about this repository is that it is not the one most application developers want. The project notes point those developers at a separate repository, KhronosGroup/OpenXR-SDK, for writing an application using the OpenXR headers and loader with minimum dependencies.

The difference between the two trees is concrete. OpenXR-SDK is based on this one but contains all generated files pre-generated, which removes the requirement for Python or build-time file generation, and it omits the samples, tests and API layers because those are not typically built as part of an application. The source tree you are looking at keeps all of that, plus the loader implementation itself and the validation layers.

So the audience splits cleanly. Application teams link against the SDK tree. Tool authors, runtime implementers, engine vendors writing their own API layer, and anyone debugging why an application behaves differently on one headset than another work in the source tree, because that is where the loader code and the layer samples live.

## What sits in each directory

The repository layout is documented in the README, which lists each directory with a one line description. The map of the project is short: `src/api_layer` holds sample code for developing API layers, `src/loader` holds the OpenXR loader code, and `src/tests` holds various test code, with the README noting that if you are looking for sample code you should start with `hello_xr/`. The remaining entries are `include/`, the OpenXR platform include file, `specification/`, the xr.xml file, and `external/`, external code for projects in the repo. The loader implementation, the layer samples and the test code are the three directories most readers come for, and `specification/` holds the `xr.xml` file from which the API headers and loader bindings are generated.

The project notes go further and state that the best sample code is currently in `src/tests/hello_xr/`, with more to be added in the future. That is an admission that the sample set is young, which matters if you were hoping for a gallery of complete applications to copy from.

The `specification/xr.xml` file is the single source from which the API headers and the loader bindings are generated. That single point of generation is why the source tree needs Python and a build-time generation step at all, and why the pre-generated SDK tree can skip it.

## API layers and validation layers are the reason to clone

An API layer is an insert between the application and the OpenXR runtime. It can intercept calls, add behaviour, or record what happened. The repository carries a dedicated sample directory for developing them, which makes this the reference place to look when you are writing a layer against the OpenXR API rather than against a specific vendor runtime.

The validation layers serve a different purpose: they exist to check whether an application is using the API correctly. Combined with the test code in `src/tests`, they give you a way to reproduce and diagnose a conformance problem instead of guessing at the vendor behaviour.

This is the part that distinguishes the tree from any other copy of the OpenXR headers. If your goal is to write an application, the loader in the SDK tree is enough. If your goal is to understand or extend what happens between the application and the runtime, the layers and the loader source are the point of the exercise, and the rest of the tree is supporting cast.

## Building from source and where the instructions live

The build instructions are not in the README. They are delegated to a separate document, BUILDING.md, listed as the first entry in the directory structure section of the README and present at the top level of the repository. Anyone starting a build should read that file rather than infer a procedure from the tree.

What the repository layout does show is the shape of the build. CMakeLists.txt at the top level is the entry point for the build system, and the top level also carries .appveyor.yml for Windows CI and a .azure-pipelines/ directory for Azure Pipelines, which tells you the project is built on more than one CI system. There is a script named open-in-docker.sh at the root and a .env file, and tox.ini, which is a Python test runner configuration and matches the generation and validation steps in the Python-based build.

There are also maintainer scripts and a checkCodespell file for spelling checks over the tree, plus runClangFormat.sh for formatting, and openxr-codespell.exclude listing the files that checkCodespell should not touch. These are the tools a contributor runs before opening a change, and the exact commands live with the build documentation.

## Bulk commits make git blame lie unless you configure it

One repository-specific detail deserves its own section because it will mislead anyone doing archaeology on the loader code. The project tracks bulk commits in the `.git-blame-ignore-revs` file, specifically so that `git blame` output points at the commit that actually changed a line rather than at a repository-wide mechanical rewrite.

The catch is that the project notes state web interfaces do not yet handle this file, so browsing the blame view on the GitHub website will still attribute lines to bulk commits. The workaround is to use the command line and point git at the ignore file. The project notes link the git documentation for the ignore-revs-file option and a blog post on using ignore-revs files for bulk change commits, which is where the mechanics are described.

This is a small thing with a large effect on review and debugging. If you are trying to find out when a particular loader behaviour was introduced and the blame view names a sweeping reformat, the answer is in that file, not in the commit the web page shows.

## Licensing, reuse tooling and the release cadence

The project is published under Apache-2.0, with the licence file at the repository root and supporting files in the `LICENSES/` directory, alongside `COPYING.adoc` for copyright and licensing information. The project notes themselves carry an SPDX identifier of CC-BY-4.0 and a Khronos copyright notice for 2017 to 2026, which is the usual arrangement for a project whose documentation is licensed separately from its code. Read `COPYING.md` as referenced in the directory listing, and the `LICENSES/` directory, before redistributing anything from the tree. This is a reading of the files, not legal advice.

The repository also uses the REUSE specification, visible in the `.reuse/` directory, a `.proclamation.json` file and its own `.proclamation.json.license` companion, and a `.gitattributes` file. That machinery exists so every file in a large multi-project tree carries a licence tag, which matters for a codebase that vendors code under `external/`.

On cadence, the releases are frequent: release-1.1.65 shipped on 2026-10-16, release-1.1.63 on 2026-09-02 and release-1.1.62 on 2026-08-01. The repository is not archived and the last push was on 2026-10-20, so code and tags are moving together. A `CHANGELOG.SDK.md` file and a `changes/` directory at the top level are where per-release notes and pending change entries live.

## Where this tree is the wrong tool

There are two clear cases for looking elsewhere.

The first is ordinary application development. If you are writing a game or a viewer, the SDK tree gives you headers and a loader with no Python requirement and no generation step at build time. Pulling the source tree in adds a generation dependency, a C++ build of the loader, and the maintenance of that build, for no benefit to an application that just needs to call OpenXR.

The second is the sample code. The project notes say the best sample code is in `src/tests/hello_xr/` and that more will be added, and the sample lives under `src/tests`, which tells you it is organised as test input rather than as a curated gallery of complete applications. If you are looking for a fully fledged reference application to study, the sibling SDK tree does not carry the samples either, so neither tree gives you that, and the honest answer is that the sample set here is a starting point rather than a catalogue.

A third consideration is review surface. This is a large multi-project tree with vendored code under `external/`. Patches here go to the public issue tracker and are accepted as pull requests, but the review norms and the review cost are those of a standards body repository, which is a different experience from an ordinary open source project.

## Conclusion

Use OpenXR-SDK-Source when you are writing an API layer, debugging a runtime, or need the validation layers to reproduce a conformance problem, since it is the only one of the two Khronos trees that carries samples, tests and layers. Do not adopt it for an ordinary application: the sibling OpenXR-SDK project ships pre-generated headers and loader with no Python or build-time generation. Verify first that your platform and toolchain appear in BUILDING.md, and read .git-blame-ignore-revs before trusting blame output on the loader code.

## FAQ

### What is the difference between OpenXR-SDK-Source and OpenXR-SDK?

The SDK project is based on this one but contains all generated files pre-generated, removing the requirement for Python or build-time file generation, and it omits the samples, tests and API layers. The source tree keeps the loader implementation, the validation layers, the API layer samples and the test code.

### Where are the build instructions for the OpenXR source tree?

They are in BUILDING.md at the repository root, which the project notes list as the first entry of the directory structure and points to instead of describing the build inline.

### Where do I find sample code for writing an OpenXR API layer?

Sample code for developing API layers is in `src/api_layer`, and the README says the best sample code overall is currently in `src/tests/hello_xr/`.

### Why does git blame on GitHub show bulk commits in the OpenXR loader?

The project tracks bulk commits in `.git-blame-ignore-revs`, but the README notes web interfaces do not yet handle that file. Using git from the command line with the ignore-revs file gives the accurate attribution.

### What licence applies to the OpenXR SDK source code?

The project is published under Apache-2.0, with the licence file at the repository root, extra licence material in `LICENSES/`, and copyright and licensing details in `COPYING.adoc`. The project notes file itself carries an SPDX identifier of CC-BY-4.0.

## Sources

- [KhronosGroup/OpenXR-SDK-Source on GitHub](https://github.com/KhronosGroup/OpenXR-SDK-Source)
- [License: Apache-2.0](https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/main/LICENSE)
- [Project website](https://khronos.org/openxr)
- [README](https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/main/README.md)
- [Releases](https://github.com/KhronosGroup/OpenXR-SDK-Source/releases)

---

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