Why Orbit?
Positioning floating UI by hand quickly turns into repeated math for viewport boundaries, arrow offsets, and scroll/resize tracking.
| Feature | Orbit | Floating UI | Popper |
|---|---|---|---|
| Bundle size | 4.7 KB | ~10 kB | ~6 kB |
| Middleware pipeline | |||
| Direct compute API | |||
| High-level follow API | Partial | ||
| Inline anchor middleware | |||
| Auto-update helpers | |||
| Framework agnostic | |||
| Zero dependencies |
Use Orbit when you want a lightweight, DOM-first positioning engine with direct control and no framework adapter requirements.
Consider larger alternatives when you need their existing integration ecosystem or migration compatibility.
Installation
sh
pnpm add @vielzeug/orbitsh
npm install @vielzeug/orbitsh
yarn add @vielzeug/orbitQuick Start
Use float() for the common case — it writes left/top and keeps the position in sync. It returns a FloatHandle; always call handle.dispose() on teardown.
ts
import { flip, float, offset, shift } from '@vielzeug/orbit';
const trigger = document.querySelector<HTMLElement>('#trigger')!;
const tooltip = document.querySelector<HTMLElement>('#tooltip')!;
const handle = float(trigger, tooltip, {
placement: 'top',
middleware: [offset(8), flip(), shift({ padding: 6 })],
});
// Call dispose when the tooltip is removed
handle.dispose();Or use presets for ready-made middleware stacks:
ts
import { float } from '@vielzeug/orbit';
import { tooltip as tooltipPreset } from '@vielzeug/orbit/presets';
const handle = float(trigger, tooltip, tooltipPreset());
handle.dispose();Features
float()covers the common position-and-follow case; returns aFloatHandlewithdispose(),update(), andgetPosition()- Custom
apply(result)callback onfloat()for transforms or custom rendering computePosition()returnsx,y,placement, andmiddlewareDatawithout touching the DOMdetectOverflow()returns per-side overflow offsets; used by built-in middleware and available for custom middleware- Global
boundaryandpaddingoncomputePosition()andfloat()— set once, all overflow-aware middleware inherit them containingBlockoption forposition: absolutefloating elements- Built-in middleware:
offset,flip,autoPlacement,shift,size,arrow,hide compose()— falsy-filter helper for building middleware arrayslimitShift()— constrainsshift()drift to keep the float visually connected to its referenceinlinemiddleware for multi-line inline references (now part of main entry)- Pre-configured presets (sub-path
@vielzeug/orbit/presets):tooltip,dropdown,popover,contextMenu autoUpdate()supports scroll, resize, ResizeObserver, visualViewport, animation frames, throttle, ancestor scroll containers, andpauseWhenHiddenvia IntersectionObservergetSide()andgetAlignment()utilities for reading placement componentsfloatWithAnchor()— CSS Anchor Positioning progressive enhancement (browser-native, no JS loop)- Reactive signal adapter (sub-path
@vielzeug/orbit/reactive) — wrapsfloat()with a@vielzeug/ripplesignal - SSR-safe no-op stubs (sub-path
@vielzeug/orbit/ssr) - Zero dependencies (optional peer:
@vielzeug/ripplefor the reactive sub-path)
Sub-paths
| Import | Purpose |
|---|---|
@vielzeug/orbit | Core API, middleware (inline included), utilities, types |
@vielzeug/orbit/presets | Pre-configured middleware stacks |
@vielzeug/orbit/reactive | Reactive signal adapter (@vielzeug/ripple) |
@vielzeug/orbit/devtools | Visual debug overlay (development only) |
@vielzeug/orbit/ssr | No-op stubs for server-side rendering |
Documentation
See Also
- Sigil — accessible web components that use Orbit internally for dropdown, tooltip, and popover positioning
- Dnd — drag-and-drop engine; use Orbit to reposition drop targets and drag previews relative to containers
- Craft — web-component authoring framework; Orbit integrates as a positioning primitive for overlay elements