Native OpenXR apps

Start from a reference app, run it without a spatial display, lint it, ship it.

No spatial display? Develop on sim-display. DisplayXR ships a simulated spatial display, so you can build, run and self-test on an ordinary monitor. You need real hardware only to see the woven 3D image and real eye tracking.

Pick your graphics API

Every API listed has a native compositor. Reach for the recommended one first.

Windows

D3D11

D3D12 for engines

Also supported: D3D12, Vulkan, OpenGL

macOS

Metal

Also supported: Vulkan (MoltenVK), OpenGL

Linux

Vulkan

Vulkan only

Android

Vulkan

Vulkan only

Quickstart

  1. 1. Install DisplayXR

    The runtime and the sim-display plug-in, from Download.

  2. 2. Start from the reference app

    test_apps/handle/cube_handle_d3d11_win in displayxr-runtime is a small, correct D3D11 app: copy it and adapt it. In Claude Code, the runtime repo's /new-displayxr-app skill does this for you: it clones the nearest reference app, adds the manifest and CMake wiring, and runs the linter until it is clean.

    Windows: build and run from source
    git clone https://github.com/DisplayXR/displayxr-runtime
    cd displayxr-runtime
    scripts\dev-setup.bat                REM once, from an elevated prompt
    scripts\build_windows.bat test-apps  REM then from a normal prompt
    _package\run_cube_handle_d3d11_win.bat

    Prerequisites: build guide.

  3. 3. Run it on sim-display

    dev-setup registers sim-display, and with no vendor plug-in DisplayXR uses it. sim-display is a simulated spatial display in an ordinary window; WASD and the mouse move the virtual eye. To use it on a machine that has a vendor plug-in, displayxr-cli dp use sim-display (undo with dp reset).

  4. 4. Lint it

    The app linter checks your source against the authoring rules. Python 3, no dependencies.

    from displayxr-runtime
    python3 scripts/check_displayxr_app.py <app-dir>
  5. 5. Ship

    Put a .displayxr.json manifest and an icon next to your binary so launchers and workspace controllers can list it. Ship a manifest.

App classes

The class decides who owns the window and the final surface. Mixing 2D and 3D is a separate choice that works in every class.

Handle
Your app owns its window and hands the runtime its handle (HWND, NSView, X11 or Wayland surface, Android Surface). The default, and the one to start from.
Texture
Something else must own the final surface (a browser composite, a capture target): you pass a shared texture, the runtime weaves into it, you present it.
Hosted
The runtime creates the window and targets, as on any OpenXR runtime. The simplest path; on Android it is fullscreen-only.
IPC
Out-of-process, through the service. Used internally by the Shell and WebXR; you still write a Handle app and IPC is transparent.

More in App classes, and the extensions each class uses on Extensions.

If something is wrong

Run the headless self-test first. It checks plug-in discovery and the display without a compositor, GPU or window, and ends with SELF-TEST PASSED when the runtime is healthy.

terminal
displayxr-cli selftest

On Windows the CLI is in C:\Program Files\DisplayXR\Runtime\.

Symptom-by-symptom fixes: Troubleshooting.