macOS-inspired controls, built for Vue.
Vue 3 components carrying AppKit metrics, states and keyboard behaviour — including opt-in Liquid Glass refraction.
Work in progress. Until 1.0 the design tokens (--macvue-* names and scales) are not a stable contract: renames and removals may land in minor releases while the library is calibrated against the macOS Tahoe reference.
- 19 components — Badge, Box, Button, Checkbox, Glass Panel, Help Button, Label, Pop-Up Button (with Pull-Down), Progress, Radio Group, Search Field, Secure Field, Segmented Control, Separator, Slider, Spinner, Stepper, Switch, Text Field.
- Five control sizes on every control that has them:
mini,small,regular,large,extraLarge— theNSControl.ControlSizescale, measured rather than guessed. - Light and dark through a single
data-macvue-appearanceattribute, on any element rather than just the page root. - System accents — every control follows
--macvue-accent. - Liquid Glass with real edge refraction, opt-in per subtree and never at the cost of a broken control where it is unsupported.
- TypeScript types included. 25 kB gzipped for the whole library, JS and CSS together.
pnpm add @macvue/coreVue 3.4 or newer is a peer dependency.
<script setup lang="ts">
import { MacButton, MacSwitch } from '@macvue/core'
import { ref } from 'vue'
import '@macvue/core/style.css'
const wifi = ref(true)
</script>
<template>
<MacSwitch
v-model="wifi"
aria-label="Wi-Fi"
/>
<MacButton variant="prominent">
Continue
</MacButton>
</template>Import macvue/style.css once, at your application entry.
Light and dark are driven by one attribute, and it works on any element — a dark panel inside a light page needs no extra wiring:
<template>
<div data-macvue-appearance="dark">
<MacButton>Cancel</MacButton>
</div>
</template>The accent colour is a token, so one declaration re-tints every control under it:
.my-app {
--macvue-accent: #bf5af2;
}Glass surfaces ship a CSS material by default. Edge refraction is opt-in: add data-macvue-glass="on" to an ancestor, and the nearest data-macvue-glass boundary wins, so a nested off disables it locally.
Controls take part too: Switch and Slider grow a refracting lens around the knob while it is held, at every size.
<template>
<div data-macvue-glass="on">
<MacSwitch
v-model="wifi"
size="extraLarge"
aria-label="Wi-Fi"
/>
<MacGlassPanel material="clear">
<span>Media controls</span>
</MacGlassPanel>
</div>
</template>Refraction is built on an SVG displacement filter applied through backdrop-filter, which currently limits it to Chromium — WebKit bug 245510 is still open. Support is feature-detected at runtime: Safari and Firefox get the CSS material fallback, prefers-reduced-transparency gets an opaque surface, and forced colors gets system colors. The control is never hidden while the check runs.
The site is not deployed yet. Run it locally:
pnpm install
pnpm docs:devpnpm install
pnpm build # build the macvue package
pnpm play # playground
pnpm docs:dev # documentation site
pnpm test # unit tests
pnpm test:browser # interaction tests (Playwright, Chromium)
pnpm lint
pnpm typecheckMacVue is an independent open source project and is not affiliated with, endorsed by, or sponsored by Apple Inc. macOS and AppKit are trademarks of Apple Inc.
Copyright (c) 2026-present, Anton Reshetov.

