# pmndrs/uikit: Flexbox UI for react-three-fiber, Not Apple's UIKit

> pmndrs/uikit renders Yoga-laid-out interfaces inside a three.js scene, with pre-styled kits based on Shadcn and Meta Horizon OS. Its documentation covers layout, fonts and performance; it does not document rollback.

**pmndrs/uikit** — 🎨 user interfaces for react-three-fiber

- Repository: https://github.com/pmndrs/uikit
- Website: https://pmndrs.github.io/uikit/docs/
- Stars: 3,246 · Forks: 178
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/pmndrs-uikit

## What pmndrs/uikit actually solves, and for whom

The name collides with Apple's framework, so the first thing to establish is what this repository is not. pmndrs/uikit is a TypeScript library for building user interfaces inside a three.js scene, aimed at games, XR (VR/AR) and what the README calls web-based Spatial Computing apps. It is a pmndrs project and its npm packages are published under the @react-three scope, with @pmndrs aliases also listed. If you arrived looking for UIButton or Auto Layout on iOS, you are in the wrong repository.

The problem it addresses is layout. Three.js gives you geometry, materials and a camera, but nothing that behaves like a box model. Positioning a label, a row of buttons or a scrollable list by hand means computing coordinates yourself, and every change to text length or screen size invalidates that arithmetic. pmndrs/uikit brings the flexbox model into the scene graph, so a container can grow, a row can wrap and a gap can be declared as a number rather than derived from measured geometry. The audience is narrow but well defined: React developers who already render with @react-three/fiber and want their interface to be part of the 3D world rather than a DOM layer floating above the canvas.

## How the layout engine and the react-three-fiber renderer fit together

The library exposes React components that map onto flexbox properties. The README's opening example is a fullscreen row containing two containers that share the space equally and change opacity on hover, and that example shows the whole mechanism in miniature: createRoot from react-dom/client mounts a React tree, Canvas from @react-three/fiber provides the renderer, and Fullscreen and Container from @react-three/uikit describe the interface. Properties such as flexDirection, padding, gap, flexGrow, opacity and backgroundColor are passed as props, and interaction states are declared as objects, which is why hover={{ opacity: 1 }} sits next to a static opacity of 0.5.

The topics list on the repository names yoga, the layout engine that resolves those flexbox declarations. That is the architectural decision worth noticing: layout is computed by a dedicated engine rather than by the browser, because there is no browser layout inside a WebGL canvas. Text measurement, sizing and responsive behaviour therefore depend on what the library feeds into that engine, and the documentation set reflects this, with separate pages for sizing, responsive interfaces, scrolling and custom fonts. Components and their properties have their own reference page, and custom materials are documented separately for cases where the default appearance is not enough. The README also points to a common pitfalls page, which is the honest signal here: a flexbox model transplanted into a scene graph has failure modes that a DOM developer will not predict.

## Installing @react-three/uikit and rendering a first layout

The README does not spell out an install command, but it does name the packages. The core package is @react-three/uikit, and the pre-styled kits install via @react-three/uikit-default or @pmndrs/uikit-default for the Shadcn-based kit, and @react-three/uikit-horizon or @pmndrs/uikit-horizon for the kit based on Meta's Horizon OS UI set. Pick one naming convention and stay with it across your dependency list, because mixing the two scopes in one project is a good way to end up with two copies of the same code.

```bash
npm install @react-three/uikit @react-three/uikit-default
```

With the packages present, the README's basic example is the shortest path to something on screen. It mounts into an element with the id root, wraps everything in a fiber Canvas, and uses Fullscreen so the layout fills the available space. The two Container elements each take flexGrow={1}, so they divide the row evenly, and the hover prop swaps opacity when the pointer is over them.

```jsx
import { createRoot } from 'react-dom/client'
import React from 'react'
import { Canvas } from '@react-three/fiber'
import { Fullscreen, Container } from '@react-three/uikit'

createRoot(document.getElementById('root')).render(
  <Canvas>
    <Fullscreen flexDirection="row" padding={10} gap={10}>
      <Container flexGrow={1} opacity={0.5} hover={{ opacity: 1 }} backgroundColor="red" />
      <Container flexGrow={1} opacity={0.5} hover={{ opacity: 1 }} backgroundColor="blue" />
    </Fullscreen>
  </Canvas>,
)
```

The expected result is a fullscreen scene with two coloured panels side by side, separated by the padding and gap values, each fading to full opacity as the pointer enters it. From there the README routes you to the first-layout guide, the examples directory, and, if you are not using react-three-fiber, a separate vanilla three.js tutorial. The examples directory in the repository is organised by scenario: auth, card, dashboard, default, horizon, lucide, market, performance, ttf-react and ttf-vanilla, plus uikit and vanilla. Those folder names are the most concrete map of what the project considers representative use.

## Where the flexbox-in-a-canvas model breaks down

The most obvious limitation is the one the README itself flags by linking a pitfalls page rather than folding the warnings into the getting-started text. Flexbox semantics were designed for a document flow that a browser maintains. Inside a canvas there is no such flow, so anything that depends on intrinsic content size, on text wrapping at a container boundary, or on the interaction between overflow and scrolling has to be reproduced by the layout engine and the renderer together. Expect to consult that page before you file a bug.

Text is the second pressure point. Custom fonts have their own tutorial, which tells you that font loading is a configuration step rather than a default. If your interface depends on a specific typeface, budget time for that setup and for how glyph metrics affect the layout the engine produces.

The third case is the wrong-tool case, and it is common. If your interface is a settings panel, a login form or a data table that sits above the 3D view, an HTML overlay positioned over the canvas is cheaper to build, accessible to screen readers by default and debuggable with browser devtools. pmndrs/uikit earns its complexity when the interface must exist in the same 3D space as the scene: attached to an object, viewed through a headset, or transformed by the same camera. Choosing it for a flat overlay means paying the layout engine's cost for nothing. Accessibility is the related gap. The README documents components, interactivity, materials, fonts, responsiveness, scrolling, sizing, theming and performance, but it does not claim screen-reader support, and nothing published about the project suggests assistive technology can reach a canvas-rendered button the way it reaches a DOM one.

## How the pre-styled kits differ from the core package, and what the alternatives are

The core @react-three/uikit package gives you layout and interaction primitives. The kits give you finished components with a theme. The default kit is described as based on Shadcn, and the horizon kit is based on Meta's Horizon OS UI set, published as a Figma community file. Both are described as themable pre-styled components, and the README links per-component documentation for each kit, with accordion as the default kit's entry point and avatar for the horizon kit. The practical difference between the two is visual language rather than capability: the default kit follows a web-application aesthetic, while the horizon kit follows the conventions of a headset operating system. If you are targeting XR, the horizon kit saves you from reinventing system-style controls; if you are building something that should feel like a web app inside a canvas, the default kit is the closer starting point.

The real alternative is not another 3D UI library but the DOM itself. React Three Fiber applications commonly render their interface as regular HTML positioned over the canvas, using the same React components, CSS and layout the rest of the web uses. That approach wins on text rendering, accessibility and tooling, and loses whenever the interface needs to be positioned in world space, occluded by geometry, or viewed through a headset where no flat overlay exists. A second alternative is building the interface from three.js primitives directly, which removes the dependency but returns you to manual coordinate arithmetic for every element. pmndrs/uikit occupies the middle ground: the flexbox mental model and React composition, paid for with a layout engine that is not the browser's.

## Maintenance, versions and the licence question

The repository is not archived, and its last push was on 2026-09-01. The release history shows a long 0.x line followed by the v1.0.0 line, with v1.0.46 dated 2025-10-16, and there is a migration guide for projects coming from Uikit 0.x. That guide matters more than usual here, because the README's own component names and package scopes changed across that boundary, and a tutorial written against 0.x may not compile against 1.x. The repository is a pnpm workspace, with packages, examples and docs as top-level entries, and the root package.json defines build:all as pnpm -r build and a test:docs script that runs a documentation check. There is no published cadence for releases in the repository, so treat the migration guide as the authority on breaking changes rather than inferring stability from the version number.

The licence is the item to resolve before adoption, not after. The repository metadata reports the licence as NOASSERTION, which means the automated classifier could not match the LICENSE file to a known template. The LICENSE file exists at the repository root, but its contents are not reproduced in the README. Read that file directly and have whoever handles licensing in your organisation confirm what it permits, particularly if you plan to ship the pre-styled kits inside a commercial product. This is a documentation gap, not a verdict: NOASSERTION says the tool could not classify the text, not that the terms are restrictive.

## Conclusion

Adopt pmndrs/uikit if your interface already lives inside a react-three-fiber Canvas and you want flexbox layout, hover states and pre-styled kits without leaving the scene graph. Do not adopt it if you are searching for Apple's UIKit, or if you need a plain HTML overlay, where the DOM and CSS remain the simpler tool. Before committing, verify which package name your setup resolves (@react-three/uikit or @pmndrs/uikit, and the matching -default or -horizon kit), check that your React and three versions satisfy the peer ranges the packages declare, and read the common pitfalls page linked from the README.

## FAQ

### Is pmndrs/uikit the same as Apple's UIKit?

No. pmndrs/uikit is a TypeScript library for building user interfaces inside a three.js scene, published under the @react-three scope, and it is aimed at games, XR and web-based spatial computing apps. Apple's UIKit is an iOS and tvOS framework with no connection to this repository.

### How do I install pmndrs/uikit?

The README names the core package as @react-three/uikit, with the pre-styled kits available as @react-three/uikit-default or @pmndrs/uikit-default, and @react-three/uikit-horizon or @pmndrs/uikit-horizon. Install the core package plus whichever kit you want, and keep to one scope convention across your dependencies.

### Can I use pmndrs/uikit without react-three-fiber?

Yes. The README says that if you want to use vanilla three.js, there is a separate tutorial for that, and the examples directory contains both ttf-vanilla and vanilla folders alongside the React ones.

### What are the pre-styled component kits in pmndrs/uikit?

There are two: a default kit described as based on Shadcn, and a horizon-kit based on Meta's Horizon OS UI set. Both are described as themable pre-styled components, with per-component documentation pages for each kit.

### What licence does pmndrs/uikit use?

The repository metadata reports the licence as NOASSERTION, meaning the classifier could not match the LICENSE file to a known template. The LICENSE file is present at the repository root, so read it directly before relying on any particular terms.

## Sources

- [Issues](https://github.com/pmndrs/uikit/issues)
- [pmndrs/uikit on GitHub](https://github.com/pmndrs/uikit)
- [Project website](https://pmndrs.github.io/uikit/docs/)
- [README](https://github.com/pmndrs/uikit/blob/main/README.md)
- [Releases](https://github.com/pmndrs/uikit/releases)

---

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