TL;DR:
- WebXR enables AR and VR directly in the browser — no app store, no install, just a URL
- Browser support is strong on Chrome/Android and Meta Quest, limited on iOS Safari (Apple restricts WebXR capabilities)
- WebXR is the right choice when distribution reach and zero-install friction matter more than performance ceiling; for complex enterprise apps, native wins
WebXR is the W3C API that lets browsers access AR and VR hardware — device orientation, camera passthrough, hand tracking, and hit testing — without requiring a native app install. In 2026 it’s the most distribution-friendly XR development path: your experience ships as a URL that opens on Android phones, Meta Quest browsers, and Windows desktops without any app review process or install barrier.
Browser Support in 2026
Understanding the current state of browser support is essential before committing to WebXR.
| Browser | AR (phone) | VR (headset) | Hand Tracking | Notes |
|---|---|---|---|---|
| Chrome (Android) | Full | Full | Yes | Best mobile AR support |
| Samsung Internet | Full | Full | Limited | Good Android fallback |
| Meta Quest Browser | Full | Full | Yes | Best standalone headset support |
| Firefox Reality | Full | Full | Yes | Available on Quest |
| Safari (iOS) | Limited | Partial | No | Apple restricts WebXR; no hit testing |
| Chrome (iOS) | None | None | No | iOS WebKit restriction — same as Safari |
| Edge (Windows) | None | Full (WMR) | No | Desktop VR only |
The iOS situation is the most significant constraint in 2026. Apple’s WebKit restrictions mean AR experiences on iPhones require either a native app (ARKit) or a workaround like 8th Wall, which provides its own camera-based AR engine that bypasses WebXR entirely. If your audience is primarily iOS, WebXR isn’t the right path — worth being upfront about that before you invest development time.
Core WebXR Concepts
The WebXR API exposes a hierarchy of concepts worth understanding before you dive into code.
XRSession is the root — you request either an immersive-ar session (passthrough camera with real-world tracking) or immersive-vr session (full immersive environment). The browser prompts the user to allow hardware access.
XRFrame provides pose data each animation frame — where the device is in space, and (if available) the positions of tracked hands or controllers.
XRHitTestSource lets you raycast against detected real-world surfaces — essential for placing virtual objects on floors, tables, or walls in AR.
XRReferenceSpace defines the coordinate system: local (relative to initial device position), local-floor (with a floor plane), or bounded-floor (for room-scale).
Building with Three.js and WebXR
Three.js is the most widely used WebGL library and has first-class WebXR support built in. The THREE.WebXRManager handles the session lifecycle; you write standard Three.js scene code and the library manages the XR rendering loop.
A minimal WebXR AR scene that places a 3D cube on a detected surface:
import * as THREE from 'three';
import { ARButton } from 'three/examples/jsm/webxr/ARButton.js';
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.xr.enabled = true;
document.body.appendChild(renderer.domElement);
document.body.appendChild(ARButton.createButton(renderer, {
requiredFeatures: ['hit-test']
}));
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera();
const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
const cube = new THREE.Mesh(geometry, material);
scene.add(new THREE.AmbientLight(0xffffff, 1.5));
// Hit test setup — places the cube where the reticle lands
let hitTestSource = null;
renderer.xr.addEventListener('sessionstart', async () => {
const session = renderer.xr.getSession();
const viewerSpace = await session.requestReferenceSpace('viewer');
hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
});
renderer.setAnimationLoop((timestamp, frame) => {
if (frame && hitTestSource) {
const hits = frame.getHitTestResults(hitTestSource);
if (hits.length > 0) {
const pose = hits[0].getPose(renderer.xr.getReferenceSpace());
cube.position.setFromMatrixPosition(new THREE.Matrix4().fromArray(pose.transform.matrix));
cube.visible = true;
}
}
renderer.render(scene, camera);
});
This ~30-line example creates a deployable AR experience. The ARButton handles the browser permission flow; hit testing finds real surfaces; the cube appears where the user points their phone.
A-Frame: Declarative WebXR
A-Frame is Mozilla’s HTML-based WebXR framework — you write XR scenes as HTML markup rather than JavaScript. It sits on top of Three.js and is the fastest path to a working WebXR scene without writing render loops.
<a-scene xr-mode-ui="enabled: true" webxr="requiredFeatures: hit-test">
<a-assets>
<a-asset-item id="model" src="product.glb"></a-asset-item>
</a-assets>
<a-entity gltf-model="#model" position="0 0 -1" scale="0.5 0.5 0.5"></a-entity>
<a-plane color="#666" rotation="-90 0 0" width="20" height="20"></a-plane>
</a-scene>
A-Frame is ideal for rapid prototyping, educational experiences, and product visualisation where the scene is relatively simple. It handles controller input, gaze interaction, and VR/AR mode switching out of the box. For complex applications with custom game logic, Three.js directly gives you more control.
Performance Limitations and When They Matter
WebXR’s performance ceiling is lower than native apps. The reasons: the render loop runs in JavaScript rather than C++/Swift/Kotlin; there’s no access to platform-specific optimisations like ARKit’s depth buffer, LiDAR mesh, or ARCore’s scene semantics; and browsers constrain memory allocation, so large 3D assets on mobile can hit limits.
In practice, WebXR handles scenes up to around 50,000 polygons and 10 simultaneous animated objects well on a 2024+ mid-range Android phone. Beyond that, frame drops become noticeable.
When WebXR is the right choice:
- Product visualisation and virtual try-on (simple models, low polygon count)
- Marketing experiences and branded AR (campaign landing pages)
- Prototyping before committing to native development
- VR 360 video experiences
- Educational content that needs broad, low-friction reach
When native is the right choice:
- Complex multi-user AR with persistent anchors
- Applications using LiDAR or depth sensing
- Enterprise tools requiring device management
- Experiences with 100,000+ polygon scenes or real-time physics
The Bottom Line
WebXR development is the right path when distribution reach and zero-install friction are the primary constraints. Chrome on Android and Meta Quest Browser give you a substantial, capable audience. The iOS limitation is real and significant — factor it into your platform decision before committing. For simple AR experiences, product visualisation, and VR content, WebXR in 2026 is more capable than its reputation suggests. Don’t dismiss it just because it’s not native.