Vee documentation
Migrating from SwiftBar / xbar
Vee is designed as a drop-in successor to SwiftBar and xbar. Your existing plugins run unchanged — migration is usually just pointing Vee at the folder you already have.
Point Vee at your existing plugins folder
- Open Vee's Plugin Manager.
- Click Choose Folder and select your existing SwiftBar or xbar plugins directory.
- Vee discovers the plugins and starts running them on the intervals encoded in their filenames.
That is the whole migration. You do not need to rename, rewrite, or re-tag anything.
What's compatible
Vee implements the xbar/SwiftBar plugin protocol, so the things you already rely on keep working:
- Filename refresh intervals —
cpu.5s.sh,mail.10m.py,backup.1h.rb, etc. Units:ms,s,m,h,d. - Menu format — the title line(s),
---to start the dropdown, and--prefixes for nested submenus. - Line parameters —
| key=valueparams such ascolor,href,bash=/shell=withparam0..N,terminal,refresh,size,font,length,alternate,disabled,key,image,templateImage. - SwiftBar extensions —
sfimage(SF Symbols),sfcolor,sfsize,symbolize,md/markdown,tooltip,checked,badge,ansi,emojize. - Metadata headers —
<xbar.title>,<xbar.desc>,<xbar.author>,<xbar.dependencies>,<xbar.var>, and the<swiftbar.*>equivalents (schedule, type=streamable, environment, and more). - Streaming plugins —
<swiftbar.type>streamable</swiftbar.type>with~~~block separators. - Cron schedules —
<swiftbar.schedule>. - Injected environment variables — Vee sets the xbar
XBARDarkModevariable and the SwiftBarSWIFTBAR*,SWIFTBAR_PLUGIN_*, andOS_*variables, so plugins that read them behave the same.
See the plugin authoring reference for the full list.
Compatibility matrix
The detail behind that list. Vee implements everything in the xbar and SwiftBar columns, and adds a column of its own.
A ✓ in the Vee-only column means the feature does not exist in xbar or SwiftBar. Those tools ignore parameters and metadata tags they do not recognise, so a plugin that uses them still runs there — it just renders without the enhancement. If you need one plugin to look right in all three, stay in the first two columns.
Line parameters
| Parameter | xbar | SwiftBar | Vee-only |
|---|---|---|---|
color, font, size, length, trim | ✓ | ✓ | |
href | ✓ | ✓ | |
shell / bash, param0…N, terminal | ✓ | ✓ | |
refresh | ✓ | ✓ | |
dropdown | ✓ | ✓ | |
alternate | ✓ | ✓ | |
disabled | ✓ | ✓ | |
key | ✓ | ✓ | |
image, templateImage | ✓ | ✓ | |
ansi, emojize | ✓ | ✓ | |
sfimage, sfcolor, sfsize, sfconfig | ✓ | ||
symbolize | ✓ | ||
md / markdown | ✓ | ||
tooltip | ✓ | ||
checked | ✓ | ||
badge | ✓ | ||
webview, webvieww, webviewh | ✓ | ||
shortcut (runs a macOS Shortcut) | ✓ | ||
header — a real AppKit section header | ✓ | ||
sparkline | ✓ | ||
progress, trackcolor, progressw, progressh | ✓ | ||
pie, donut, stackedbar | ✓ | ||
chartlabels, chartcolors, chartw, charth | ✓ | ||
toggle, slider — interactive popover controls | ✓ | ||
accessory — which edge an accessory anchors to | ✓ |
Metadata headers
| Tag | xbar | SwiftBar | Vee-only |
|---|---|---|---|
<xbar.title>, <xbar.version>, <xbar.author>, <xbar.author.github> | ✓ | ✓ | |
<xbar.desc>, <xbar.image>, <xbar.dependencies>, <xbar.abouturl> | ✓ | ✓ | |
<xbar.var> — typed preferences | ✓ | ✓ | |
<swiftbar.schedule> — cron | ✓ | ||
<swiftbar.type>streamable</swiftbar.type> | ✓ | ||
<swiftbar.runInBash>, <swiftbar.refreshOnOpen> | ✓ | ||
<swiftbar.environment> | ✓ | ||
<swiftbar.persistentWebView> | ✓ | ||
<swiftbar.hideAbout>, hideRunInTerminal, hideLastUpdated, hideDisablePlugin, hideSwiftBar | ✓ | ||
<vee.filter> — searchable filter panel | ✓ | ||
<vee.shortcut> — global hotkey | ✓ | ||
<vee.surface> — widget surface | ✓ | ||
<vee.timeout> — per-plugin execution timeout | ✓ | ||
<vee.capabilities>, <vee.network>, <vee.secrets>, <vee.filesystem.read> / <vee.filesystem.write>, <vee.exec> — trust declarations | ✓ |
Vee reads both the <xbar.*> and <swiftbar.*> spellings wherever they overlap,
and ignores any tag it does not recognise rather than erroring — so a plugin
written for a newer xbar or SwiftBar than Vee knows about still runs.
Output formats
| Format | xbar | SwiftBar | Vee-only |
|---|---|---|---|
The text protocol (---, --, | key=value) | ✓ | ✓ | |
Streaming with ~~~ separators | ✓ | ||
JSON output ({"vee": 1}) | ✓ | ||
Widget cards (VEE_TARGET=widget) | ✓ |
Portability in one line
<vee.*> tags live inside comments, so they are inert everywhere else — a plugin
carrying trust declarations is still a perfectly ordinary xbar plugin. Vee-only
line parameters are the ones to think about: they degrade to nothing, so the
row still appears, just plain.
What's different (and better)
- Native and leak-free. Vee is pure Swift/AppKit — the menu bar is a real
NSStatusItem/NSMenu, with no embedded WebView. Subprocess output is drained incrementally and processes are timed out and killed, so long-running use does not leak memory the way an old WebView-based architecture can. - A trust/transparency layer. Plugins can declare what they touch — network domains, filesystem paths, secrets, external binaries — with
<vee.*>tags. Vee shows a plain-language summary before you install a catalog plugin and trust badges in the Manager. It is advisory, not a sandbox. See the trust model. - Discover. A built-in browser over the shared matryer/xbar-plugins catalog, with trust chips and one-click install through the trust gate.
- Auto-generated preference forms.
<xbar.var>declarations become a typed settings form; secret fields are masked and stored in the macOS Keychain. See preferences. - Optional typed SDKs. Zero-dependency SDKs for TypeScript, Python, and Go let you build plugins with
Menu/Sectionbuilders instead of hand-formatting text. See the SDK docs.
A note for xbar users
xbar and SwiftBar share the same core plugin format, and Vee reads both dialects. If you are coming from xbar, everything above applies — point Vee at your xbar plugins folder and they run. Vee also injects xbar's XBARDarkMode environment variable for plugins that switch appearance based on it.
Caveats
- macOS 26+ only. Vee uses the newest system APIs; earlier macOS versions are not supported.
- Apple Silicon only. Vee is arm64; there is no Intel build.
- Interpreters still need to be installed. As with SwiftBar, a Python/Ruby/Node plugin only runs if that interpreter is on your system. If a plugin declares
<xbar.dependencies>, make sure those tools are present. See Troubleshooting. - Un-sandboxed by design. Plugins run with your full user privileges. That is the same model as xbar/SwiftBar; Vee makes it more transparent but does not isolate plugins. Read the trust model before installing plugins you do not trust.