Library / SDK
floating-ui/floating-ui avatar
floating-ui/floating-ui

Floating UI splits interactions out, and react-dom is where you pay for them

GitHub describes it as A JavaScript library to position floating elements and create interactions for them.. The repository metadata lists TypeScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

32,751 stars1,712 forksTypeScriptMIT

At a glance

What is it?
Floating UI anchors tooltips, popovers and dropdowns and keeps them out of viewport collisions, and it ships as a set of packages rather than one. The decision that matters at install time is whether you take the React interaction hooks along with the bundle weight, since those hooks exist for React only.
Who is it for?
Floating UI is the right pick when you need collision-aware positioning and, on React, accessible interaction primitives you would otherwise hand-build. Skip it when you want a finished tooltip component, since the markup, styling and behaviour around the position are yours to write, and skip the React packages entirely if you are on Vue or plain JavaScript and only want positioning.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Interactions are a React feature, positioning is the portable part

The library states two main features and they are not equally portable. Anchor positioning, anchoring a floating element to another element while keeping it in view by avoiding collisions, is described as available for all platforms. User interactions for React, hooks and components for composing accessible floating UI components, is scoped to React.

That split decides who gets what. On the DOM, Canvas or Vue side you receive a positioning function and nothing else, so focus movement, dismissal on outside click, and the ARIA wiring between a trigger and its panel are code you write and test yourself. On React those same concerns arrive as composable hooks.

The alternative to consider here is Tippy, which is not described in this repository. The difference in approach follows from the design: Floating UI is a set of low-level features that positions an element and hands the rest back to you, while a finished component library arrives with its own markup, styling and behaviour already decided.

Five install commands, and one of them is a size decision

The packages split by target, and the React DOM line splits a second time. Vanilla JavaScript on the web is one install:

shell
npm install @floating-ui/dom

React DOM offers two, and the difference is stated in the comments above them:

shell
# Positioning + interactions
npm install @floating-ui/react

# Positioning only (smaller size)
npm install @floating-ui/react-dom

Then React Native, Vue, and a core package for anything you have to build a Platform for yourself, which is the route named for Canvas, WebGL or any other JavaScript-capable target.

shell
npm install @floating-ui/vue
shell
npm install @floating-ui/core

Choosing `@floating-ui/react-dom` is a decision about bytes made before you have written a line of code, and the cheaper package is the one without the accessibility hooks. A CDN build is documented as well, at the getting-started page on the project site.

The browserslist floor is Safari 12, which is the number to plan around

The monorepo's package.json carries a browserslist with six entries: Chrome >= 73, Firefox >= 78, Edge >= 79, Safari >= 12.0, iOS >= 12.0 and Opera >= 53. That is the target the shipped code is compiled for.

Two consequences follow. There is no Internet Explorer anywhere in the list, so an application that still has to run there cannot use this library at all. And the floor is old enough to constrain the output: if you bundle Floating UI into a project that keeps the same floor for its own code, your application inherits the constraint even where you never touch the library, because your build pipeline is now transpiling to the same baseline.

The engine constraint is separate and stricter. `engines` requires Node >= 20.19.0 and pnpm >= 8.13.1, and `packageManager` pins [email protected], so the toolchain is defined down to the patch version of the package manager.

Popper v2 is still on its own branch, and master is the successor

A note at the top of the README says Popper is now Floating UI. For anyone still on Popper v2, the project points at a dedicated v2.x branch and at separate documentation hosted on popper.js.org, and it links a migration guide for moving across.

The arrangement tells you where fixes land. v2.x is where Popper v2 lives and where its documentation describes it, while the default branch is master and carries the Floating UI line. A patch to a v2 line and a fix to the current library therefore live in different places, and merging between them is not a fast-forward.

This also means the comparison is not really between two rival libraries. Anyone running Popper v2 today is running earlier code from this same repository, under a different package name, and the migration guide rather than a changelog diff is the document that explains what changed.

Three packages released the same day, on three different version lines

The three most recent releases are `@floating-ui/[email protected]`, `@floating-ui/[email protected]` and `@floating-ui/[email protected]`, all published on 2026-07-11. One day, three unrelated version numbers.

The packages are versioned independently, which means there is no single number to pin. `@floating-ui/vue` is past 2.0 while `@floating-ui/react` is still under 1.0 at 0.27, and the shared `@floating-ui/utils` sits at 0.2. For a React adopter that combination means holding a pre-1.0 package where a minor bump is free to change behaviour, and it means your lockfile has to name versions per package rather than one Floating UI version.

There is also a gap between publishing and development. The last release was on 2026-07-11 and the last push to the repository was on 2026-09-18, so two months of work exist on master that no published version contains. Contributors who want what is newest are building from the branch, not installing a tag.

Positioning is checked with Playwright screenshots, and both playgrounds want port 1234

The testing ground for positioning logic is visual rather than assertion-based. `pnpm run --filter @floating-ui/dom dev` in the root launches the `@floating-ui/dom` development visual tests at `http://localhost:1234`. The playground writes each test route in React and bundles it with Vite, Playwright takes screenshots of every route, and UI controls below the main container switch state and options on so that combinations get covered by the snapshots.

The React package has its own launcher, `pnpm run --filter @floating-ui/react dev`, and the README gives it the same `http://localhost:1234` address. Two dev servers claiming one port means you run them one at a time rather than side by side, which is a small thing that costs an hour the first time it happens.

Snapshots are also the acceptance gate for a change to positioning, so a pull request that shifts a placement shows up as a diff of images. The unit side is handled separately through vitest, with `@vitest/browser-playwright` in the toolchain, so behaviour and appearance are checked by different mechanisms.

A turbo pipeline ships the browser extension alongside the packages

The workspaces are declared as `./packages/*` plus two named directories, `extension` and `config`, and every script in package.json is a thin wrapper around turbo: `lint`, `format`, `test`, `build`, `typecheck`, `clean`, `publint` and `prepack`. A release runs `turbo prepack && turbo publint && changeset publish`, with versioning handled by `.changeset/` and orchestration by `turbo.json`.

Two things in there are worth knowing before you contribute. The `extension` workspace is a browser extension that ships through the same pipeline as the published packages, so a release is not confined to `packages/`. And `publint` runs before publish, which is why `@microsoft/api-extractor` is in the dev dependencies: the public surface is checked and packaged rather than assumed.

The contributing steps are three commands, `pnpm install` in the root and then a build to produce the initial package dist files.

bash
pnpm install
pnpm run build

Node >= 20.19.0 and pnpm >= 8.13.1 are the stated requirements, with [email protected] pinned in `packageManager` and an `.nvmrc` at the root.

Editorial conclusion

Floating UI is the right pick when you need collision-aware positioning and, on React, accessible interaction primitives you would otherwise hand-build. Skip it when you want a finished tooltip component, since the markup, styling and behaviour around the position are yours to write, and skip the React packages entirely if you are on Vue or plain JavaScript and only want positioning. Check three things before installing: which of `@floating-ui/react` and `@floating-ui/react-dom` you actually need, because only the first carries the interactions; whether your browser floor matches the browserslist entry, which stops at Safari 12.0 and iOS 12.0; and which Popper version your existing code is on, because v2 stays on the v2.x branch while new work lands on master.

Frequently asked questions

How do I install Floating UI?

It is installed per platform. Vanilla JavaScript on the web is `npm install @floating-ui/dom`, React DOM is `npm install @floating-ui/react` or `npm install @floating-ui/react-dom` for positioning only, React Native is `npm install @floating-ui/react-native`, Vue is `npm install @floating-ui/vue`, and Canvas or another platform is `npm install @floating-ui/core` so you can build your own Platform.

How does Floating UI work?

Floating elements are absolutely positioned and usually anchored to another UI element, which is hard to keep correct inside scrolling containers. When a floating element ends up too close to the viewport edge it becomes obscured, which the project calls a collision, and the position has to be adjusted so it stays visible.

What is Floating UI React and how is it different from the DOM package?

The React package comes in two forms. `npm install @floating-ui/react` gives positioning plus interactions, while `npm install @floating-ui/react-dom` is positioning only and smaller. Those interactions are the hooks and components for composing accessible floating UI components, the second of the project's two main features.

Floating UI vs Popper: what changed?

The project states that Popper is now Floating UI. Popper v2 lives on a dedicated v2.x branch with its own documentation on popper.js.org, and a migration guide covers moving across, while the default branch is master and carries the current line.

Floating UI vs Tippy: which one should I pick?

Tippy is not covered in this repository, so the comparison comes down to the level each one works at. Floating UI positions an element and avoids collisions as a set of low-level features, leaving the markup and styling to you, whereas a finished component library supplies its own.

What is Floating UI used for?

It creates floating elements such as tooltips, popovers and dropdowns, anchoring one to another element while keeping it in view, and for React it also provides hooks and components for composing interactions. The tutorial on the project site teaches the basics by building a basic tooltip, and the API documentation covers computePosition.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/floating-ui-floating-ui.svg)](https://hysenlabs.com/projects/floating-ui-floating-ui)