npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@realitycollective/webxr-input

v0.1.9

Published

Shared, engine-free input contracts for the Reality Collective WebXR extension families: normalised input sources (rays, pinches, pokes, grips, hand joints, gaze, 2D pointers), capability negotiation, a pull-based provider interface, and pointer streams -

Readme

@realitycollective/webxr-input

Plain TypeScript types describing XR input: where a hand or controller is pointing, what it is touching, and what the device can actually do.

No dependency on any 3D engine, and no runtime dependencies at all. A test enforces both.

npm install @realitycollective/webxr-input

What it is

A shared vocabulary for input. It lets an interaction library, a UI library and an engine adapter agree on what "input" means, without any of them importing a 3D engine.

| Concept | What it gives you | | --- | --- | | Input sources | Normalised rays, pinches, pokes, grips, hand joints, gaze and 2D pointers, addressed by handedness rather than array index | | Capabilities | What the current device can actually do, so a feature can switch itself off and say so rather than failing silently | | Eye gaze | The gaze-and-pinch rule Meta IWSDK 1.0.0 applies when a session grants eye tracking (the primary input on Meta VR Glasses), as pure logic every provider runs: EyeGazeInput, EYE_GAZE_DEFAULTS, EyeGazeFilter. See src/eye-gaze.ts | | Provider | The interface an engine adapter implements once. Consumers ask it for the current state each frame; it never pushes at them | | Pointer streams | Press, move and release events for one input source, with no reference to the engine's scene graph | | Pointer arbitration | PointerArbiter: one decision per source (touch, grab or ray) across every target set that offers candidates, with IWSDK's priority and selection lock; PointerVisuals name the panel or object the pointer is on | | Pointer display | PointerDisplay and POINTER_DISPLAY_DEFAULTS (IWSDK 1.0.0's look): the app's ray and cursor settings, and pointerDrawing(), which turns a decision into what a binding draws | | Conformance suite | inputProviderContractCases(), the checks every provider must pass, shipped as data; MemoryInputProvider is the in-memory reference provider for tests and tools |

It deliberately contains no raycasting, no scene-graph types and no session management - those belong to the engine adapters that sit on top.

Who consumes it

Both families read the same contracts, so one engine adapter feeds both. That includes the native one: @realitycollective/native-interactions implements InputProvider over the input slice a native XR app provides, so an app built on these contracts runs unchanged in a native host.

Usage

import {
  satisfies,
  unmetRequirements,
  type InputCapabilityRequirement,
  type InputProvider,
} from "@realitycollective/webxr-input";

// Ask what the current runtime supports before enabling a behaviour. A
// requirement is a name from INPUT_CAPABILITY_REQUIREMENTS: "rays", "pokes",
// "grabs" (pose-only or native), "grabsNative", "handJoints", "pinch",
// "buttonsAxes", "gaze", "eyeGaze", "pointer2d", "headPose", "haptics" or "presence".
const required: InputCapabilityRequirement[] = ["rays", "grabsNative"];

// satisfies() checks one requirement; unmetRequirements() filters a list.
if (!satisfies(provider.capabilities, "rays")) {
  console.warn("no ray targeting on this runtime");
}
const missing = unmetRequirements(provider.capabilities, required);
if (missing.length > 0) {
  console.warn("degraded:", missing); // e.g. ["grabsNative"] on a runtime without native grab
}

The two rules every family shares beyond the contracts themselves:

  • PointerArbiter decides once per source which pointer (touch, grab or ray) owns it, across registered interactables and UI panels alike, as IWSDK's MultiPointer does; the Interactions runtime and the UI Extensions window hosts register a target set each and offer their candidates. Pass one arbiter to both setups (pointers) so a touch on a panel retires the ray over an object and a panel cursor is reported.
  • PointerDisplay holds the app's ray and cursor settings (ray: "never" | "always" | "whileHitting", cursorOnObjects, cursorOnPanels, rayOnlyOnPanels, the look), IWSDK 1.0.0's values by default, settable at run time; pointerDrawing() turns the arbiter's decision into what a binding draws.

Guarantees

  • No engine imports. three, @iwsdk/*, @pmndrs/* and xrblocks are all forbidden in src/ and gated by a test that fails the build if one appears.
  • No runtime dependencies. dependencies and peerDependencies are asserted empty by the same test, so adding this package can never pull an engine into a consumer's tree.

Documentation

The full ecosystem survey, the prior-art comparison and the rationale for a separate contracts package live in the repository README.

License

MIT - see LICENSE.