Peter Hajas

My Custom Stream Deck Toolkit

August 1, 2021

My Stream Deck and its buttons

Last September, I bought an Elgato Stream Deck XL. It's a USB input device with 32 programmable buttons, each with an individual display. I think the target market is video game streamers, who use it to switch cameras, control lighting, play sound effects, and do star wipe transitions. I don't stream video games, but I've found myself using the Stream Deck frequently with my computer. This post shows what I'm doing with it and how I built it.

Hammerspoon and hs.streamdeck

I don't use the Elgato Stream Deck software. Instead, I use Hammerspoon, the amazing macOS customization tool I've had for years on my systems. You configure it with Lua files, and there is a module for using the Stream Deck called hs.streamdeck. This module lets you:

My Stream Deck Toolkit

Navigation Stacks in my toolkit

Using the Hammerspoon support, I built a declarative toolkit for populating the Stream Deck as part of my dotfiles. I define buttons as Lua tables with simple properties like image and onClick callbacks. My toolkit also supports navigation stacks, scrolling, and "panels" - buttons where X and Y on the grid are important (like in the number pad and clone window buttons below).

This toolkit lets me write buttons very easily, and experiment with new functionality quickly. Making it easy to iterate was essential to my success with this project. For example, the button to lock my computer is a few lines of Lua:

lockButton = {
    ['name'] = 'Lock',
    ['image'] = streamdeck_imageFromText('🔒'),
    ['onClick'] = function()
        hs.caffeinate.lockScreen()
    end
}

(lock emoji added for clarity - I use the lock.fill symbol from SF Symbols on my system)

My Buttons

Here are the buttons I use in my personal configuration at home:

The colored buttons at the bottom are nonce buttons. They show a random color and cycle between it at an interval, because it looks cool.

If you like what you see, or if you end up using my toolkit, please write me an email!