Web & Browser APIs · Sensei Daily Card
Technical poster: WebXR session request, reference spaces, frame loop and AR hit testing, with the 90Hz frame budget

Putting a Hologram on Your Table Through a Web Page

The browser API that hands your code a position in the real room, sixty to ninety times a second.

WEBXR DEVICE API

Core Concept

WebXR is the browser API that replaced WebVR, and its core job is exactly one thing: give your code a POSE every single frame — where the headset or phone is, expressed in a coordinate system the real room agrees with. Everything else you see in a browser-based AR demo is built on top of that one guarantee.

The most common misreading is that WebXR draws things. It does not. It is a device API, not a renderer. WebXR hands you matrices; WebGL or Three.js still has to turn those matrices into pixels.

Key Components

The Session

immersive-vr | immersive-ar

You request a session and declare which mode you want. VR replaces the world; AR composites over the camera feed of the real one.

The Reference Space

viewer · local · local-floor · bounded-floor

This defines what the origin MEANS: the device itself, wherever it started, the floor beneath it, or a room outline you may actually walk around in.

The Frame Loop

requestAnimationFrame → getPose → draw

Every frame you ask the session for the current pose and draw from it. Miss a frame and the world lags behind the head that moved.

Hit Testing (AR only)

XRHitTestSource

How a virtual object lands on your actual table: cast a ray from the screen, and the browser returns where it met a real surface it detected.

How It Works

  1. Serve over HTTPS and wait for a real user gesture — pose data is effectively a room scan, so the browser refuses to start one on page load.
  2. Request a session: navigator.xr.requestSession('immersive-ar'). If the browser cannot do that mode, you find out here, not later.
  3. Choose a reference space. Pick local-floor if objects should sit on the ground; bounded-floor if the user will walk.
  4. Run the frame loop. Each callback gives you an XRFrame; ask it for the viewer pose in your reference space.
  5. Take the view matrices out of that pose and render with WebGL/Three.js — once per eye in immersive mode.
  6. For AR placement, request a hit-test source, read the returned surface pose, and put the object there instead of guessing a depth.

The Constraint People Design Past

90HzTARGET RATE
11 msPER FRAME
×2EYES TO DRAW

This is a hard real-time budget with a physiological penalty. At 90Hz you have about 11 milliseconds to produce two eyes' worth of image. Blowing that budget does not merely look janky the way a slow web page does — the mismatch between what the inner ear reports and what the eyes see makes people nauseated within minutes. A dropped frame here costs you the user's body, not just their patience.

Where It Actually Shows Up

  • Furniture and product preview — place a real-scale sofa on your floor from a product page, no app install.
  • Training and procedure walkthroughs — an overlay pinned to a real machine, shipped as a URL.
  • Museum and site guides — reconstructions anchored to the spot you are standing on.
  • Data and model review — walk around a 3D scan or CAD assembly in immersive-vr straight from a browser tab.
  • Distribution itself — the real pitch of WebXR is a link instead of a store listing.

⚠ "Works in the browser" quietly means "works in some browsers"

Support is genuinely uneven. iOS Safari still does not ship immersive-ar — so a WebXR AR demo that works on an Android phone can be simply unavailable on an iPhone, and no amount of polyfilling gives you real surface detection there.

Always feature-detect with navigator.xr.isSessionSupported() before you promise the user a button, and design a non-XR path that is a real experience rather than an apology.

Checkpoint — answer before you move on

  1. WebXR gives you a pose every frame. Explain why choosing local-floor instead of local changes where a virtual object appears — and when bounded-floor is the only correct choice. Hint: the reference space defines what the origin means, not how the object is drawn.
  2. Why is a missed frame in WebXR a categorically different failure from a missed frame on a normal web page? Name the budget in milliseconds and the mechanism behind the penalty. Hint: 90Hz, two eyes, and a disagreement between the inner ear and the eyes.
  3. A colleague says "WebXR renders the AR scene for us." Correct them precisely: what does the API actually return, and what still has to be built on top? Hint: device API vs renderer. Matrices vs pixels.

Try It Today

Take any WebXR scene you can run and cap your frame budget at 8 milliseconds — deliberately tighter than 11. Then see what you are forced to cut: shadow quality, polygon count, post-processing, physics steps. The list of things you sacrifice at 8ms is the honest specification of what your experience can contain.