MacBuds: A Simple macOS Menubar App for Managing Bluetooth Devices

If you're like me and frequently use Bluetooth devices with your Mac, you know the pain of having to open System Settings, navigate to the Bluetooth menu, and click through multiple options just to connect or disconnect a device. Today, I want to introduce MacBuds, a lightweight menubar application that makes managing your Bluetooth devices a breeze.

What is MacBuds?

MacBuds is a simple, efficient menubar application for macOS that lives in your menubar and provides quick access to connect and disconnect your favorite Bluetooth device. While it was originally designed with earbuds in mind (hence the name), it works with any Bluetooth device paired with your Mac.

Features

  • Quick Access: Control your Bluetooth device directly from the menubar
  • Device Selection: Choose from any of your paired Bluetooth devices
  • Connection Status: Clear visual indicators show whether your device is connected (✓) or disconnected (×)
  • Launch at Login: Option to automatically start MacBuds when you log in
  • Native Experience: Built as a proper macOS application with native UI elements

How It Works

MacBuds uses blueutil under the hood, a powerful command-line utility for managing Bluetooth devices on macOS. The application is written in Go using the systray package for menubar integration and zenity for native dialogs.

When you first launch MacBuds, you'll see a simple "BT" icon in your menubar. Click it to see options for:

  • Viewing the current connection status
  • Connecting/disconnecting your selected device
  • Choosing a different Bluetooth device
  • Enabling/disabling launch at login
  • Quitting the application

Technical Implementation

The application is structured as a proper macOS bundle (.app) and includes several interesting technical features:

Configuration Management

MacBuds stores its configuration in the user's configuration directory:

configPath := filepath.Join(configDir, "bluetooth-menubar", "config.json")

The configuration includes the MAC address and name of your selected device, making it persistent across launches.

Launch at Login Support

The app implements macOS's launch at login functionality using a LaunchAgent:

func enableLaunchAtLogin() error {
    plistContent := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.rc6.macbuds</string>
        <key>ProgramArguments</key>
        <array>
            <string>%s</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
    </plist>`, getExecutablePath())
    // ...
}

Packaging

One of the most interesting aspects is how the application is packaged. The build.sh script creates a proper macOS application bundle that includes:

  • The main binary
  • A bundled copy of blueutil
  • Proper Info.plist with application metadata
  • LSUIElement flag set to true (hiding the app from Dock)

Building From Source

If you want to build MacBuds from source, the process is straightforward:

  1. Ensure you have Go installed
  2. Install blueutil: brew install blueutil
  3. Clone the repository at https://github.com/nilicule/macbuds
  4. Run ./build.sh 1.0.0 (replace with desired version)

The build script will create a properly packaged macOS application bundle in the releases directory, along with a zip file ready for distribution.

Conclusion

MacBuds demonstrates how a simple utility can significantly improve your daily workflow. While macOS's built-in Bluetooth management is functional, having quick access through the menubar makes the experience much more pleasant.

The project also serves as a good example of how to create a proper macOS application bundle for a Go program, complete with launch at login support and proper packaging. Whether you're looking to manage your Bluetooth devices more efficiently or learning about macOS application development, MacBuds has something to offer.

This article was updated on

Comments