Draggable Windows
Drag windows with pointer capture for reliable tracking
Glazier provides unstyled, fully accessible window management components for React. Build desktop-like interfaces with draggable, resizable windows—bring your own UI.
Draggable Windows
Drag windows with pointer capture for reliable tracking
Resizable
Resize from 8 directions (n, s, e, w, ne, nw, se, sw)
Snap-to-edges
Visual preview with left/right 50% split
Window States
Maximize, minimize, restore with bounds memory
Desktop Icons
Grid snapping, drag support, and multi-select
Headless Design
Zero styles included, full control over appearance
The latest version introduces powerful abstractions to reduce boilerplate:
defineWindows - Unified configuration for windows, icons, and routesWindowFrame composables - Pre-built TitleBar, Title, WindowControls, ContentResizeHandles - Ready-to-use resize handles componentuseIconLauncher - Hook for “open or focus” desktop icon patterncreateRegistry - Type-safe component registry helpercreateBrowserAdapter - Framework-agnostic URL routingGlazier provides behavior, not appearance. Components handle positioning, state management, and user interactions—you provide all styling. This gives you complete control over the look and feel.
Instead of maintaining separate configs for windows, icons, and routes, define everything in one place:
import { defineWindows } from 'glazier/server';
const windows = defineWindows({ home: { title: 'Home', defaultPosition: { x: 100, y: 100 }, defaultSize: { width: 400, height: 300 }, path: '/', icon: { label: 'Home', iconKey: 'home', position: { x: 20, y: 20 }, }, }, settings: { title: 'Settings', defaultPosition: { x: 150, y: 150 }, defaultSize: { width: 350, height: 400 }, path: '/settings', },});
// Use the helperswindows.getWindowState('home'); // WindowState for openingwindows.getIconConfigs(); // All icon configswindows.getPathMap(); // { home: '/', settings: '/settings' }Reduce window chrome boilerplate from ~70 lines to ~15:
import { WindowFrame, TitleBar, Title, WindowControls, Content, ResizeHandles,} from 'glazier';
function MyWindow({ windowId }: { windowId: string }) { return ( <WindowFrame windowId={windowId} enableDoubleClickMaximize enableSnapToEdges> <TitleBar className="h-10 bg-slate-900"> <Title /> <WindowControls /> </TitleBar> <Content className="p-4">Your content here</Content> <ResizeHandles windowId={windowId} minWidth={300} minHeight={200} /> </WindowFrame> );}For apps with multiple window types, use the registry pattern with type safety:
import { createRegistry } from 'glazier';
const registry = createRegistry(windows.ids, { home: HomeWindow, settings: SettingsWindow,});
<WindowManagerProvider registry={registry}> <Desktop> {({ Component, windowId, componentProps }) => ( <Window id={windowId}> <Component windowId={windowId} {...componentProps} /> </Window> )} </Desktop></WindowManagerProvider>