app.tray(options) creates a system tray icon and menu, backed by
@trayjs/trayjs (Windows, macOS, Linux).
const tray = app.tray({
icon: {
png: "./dist/icons/icon32.png", // macOS / Linux
ico: "./dist/icons/icon.ico", // Windows
},
tooltip: "My App",
onMenuRequested: () => [
{ id: "open", title: "Open" },
{ separator: true },
{ id: "quit", title: "Quit" },
],
onClicked: (id) => {
if (id === "open") app.window.show();
if (id === "quit") app.close();
},
});icon.png/icon.ico- paths to icon files. Use the icons generated by the build script (see Icons) under{outDir}/icons/.tooltip- text shown when hovering the tray icon.onMenuRequested- called each time the user opens the tray menu. Can return a plain array or aPromisethat resolves to one, so the menu can be built dynamically. Items are{ id, title, enabled?, checked?, items? }(for submenus) or{ separator: true }.onClicked(id)- called with theidof the clicked menu item.
app.tray() returns the underlying Tray instance from @trayjs/trayjs for
further control (e.g. tray.destroy()).
@trayjs/trayjs ships a separate native binary package per platform
(@trayjs/win32-x64, @trayjs/darwin-arm64, etc.), installed automatically
based on the machine you run bun install on - only the matching platform's
package is installed, even though all of them are listed as dependencies.
If you cross-compile for multiple targets from a single machine (e.g. building
bun-linux-x64 and bun-darwin-arm64 from Windows), app.tray() will work on
the host platform but throw at runtime on the others, since their native
binaries were never installed/bundled.
To support app.tray() on every platform, build each target on its native OS -
e.g. a GitHub Actions matrix with windows-latest / macos-latest /
ubuntu-latest runners, each running bun install + bunx buntop build release for its own target(s).
Alternatively, if you'd rather build everything from a single machine, you can manually install every platform package so they're all available to bundle:
| Package | Description |
|---|---|
@trayjs/trayjs |
Node.js API |
@trayjs/linux-x64 |
Native binary for Linux x64 |
@trayjs/linux-arm64 |
Native binary for Linux arm64 |
@trayjs/darwin-x64 |
Native binary for macOS x64 |
@trayjs/darwin-arm64 |
Native binary for macOS arm64 |
@trayjs/win32-x64 |
Native binary for Windows x64 |
@trayjs/win32-arm64 |
Native binary for Windows arm64 |
bun add @trayjs/linux-x64 @trayjs/linux-arm64 @trayjs/darwin-x64 @trayjs/darwin-arm64 @trayjs/win32-x64 @trayjs/win32-arm64 --force--force is needed since these are platform-restricted optional dependencies
that bun normally skips if they don't match your host OS/arch. Each package is
small (~150-200KB), so installing all of them is cheap.