Inspiration
Every deep work session used to start the same way: close fifteen browser tabs by hand, quit Slack, pause whatever music was playing, dig up the "focus" playlist, dim the lights, etc., and then finally start working. By the time the environment was ready, so was the next distraction.
We wanted one click to do all of it - apps launching, distractions being blocked, lights dimming, music starting, so "starting to focus" stops being its distraction.
What it does
What it does
Monolith is a desktop app that turns "starting to work" into a single action instead of ten small ones.
You define moods, such as Deep Work, Brain Dump, High Energy, Late Night Chill, or anything else. For each one you describe, what you want your environment to do. Monolith discovers your installed apps, your Philips Hue bridge, and your Spotify account, then maps that intent onto real hardware and software:
- Lighting: Hue bulbs shift color and brightness to match the mood
- Sound: a Spotify playlist or station starts automatically
- OS focus: macOS Focus mode is set to match, silencing notifications
- App blockade : distracting apps you've named are killed the instant you engage, and kept dead for the entire session - if you reopen Slack mid-session, Monolith closes it again on its next check
- Scheduling: moods can auto-engage and auto-disengage on a weekly schedule, no manual toggle required
- Menu bar + global hotkey — engage or disengage from anywhere with
⌘⇧M, without switching to the app - Session stats — every session is logged locally with duration and apps blocked, rolled up into today's minutes and a day-streak
Disengaging reverses the shift — lights and focus mode return to neutral — but deliberately does not reopen the apps it closed, so you don't walk back into the same fifteen tabs that got you off track in the first place.
Sign in with an account and your schedules and session history sync to the cloud via Supabase, so your setup follows you across machines.
How we built it
The Electron desktop app is the brain. Tt launches and closes apps, reads your saved profiles, and connects smart lights and Spotify.
For the physical/sonic layer, the main process makes direct HTTP calls: a PUT to the Hue bridge's group-action endpoint for lighting, and calls to the Spotify Web API for playback — both designed to degrade gracefully rather than block the rest of the shift if a bridge is offline or a token's expired.
Challenges we ran into
- Local calendar days, not UTC. Streak and "minutes today" calculations that used UTC day boundaries quietly broke for anyone not near GMT — a session at 11pm and one at 1am could land on the "same day" by UTC math while feeling like two different days to the user. We rebuilt the day-key logic around the local calendar day instead.
- The scheduler's dedup key. An early version tracked a single "last fired" string, which meant two moods scheduled in the same minute would clobber each other's fire state. Keying dedup per
(action, profileId)instead of globally fixed it. - Desynced engaged-state. With the tray, the hotkey, the scheduler, and the window all able to trigger an engage or disengage, letting each one track its own "is this on" boolean was a recipe for the tray showing "Engage" while a mood was actually running. Consolidating everything onto one shared state source removed an entire class of bug.
- Looking like "Electron," not like a real app. Running via
npm startmeant the OS was quite literally reporting the identity ofnode_modules/electron/dist/Electron.app— no amount of in-app renaming changes what the Dock or Activity Monitor shows, because that identity lives in the packaged bundle's ownInfo.plist. The fix wasn't a rename, it was actually packaging the app. - Verifying cloud sync wasn't just testing the happy path. Signing up, signing in, and writing a row is the easy 80%. We also confirmed, against the live database, that a signed-out client reading the exact same rows a signed-in user just wrote gets back zero results — proving Row Level Security was actually enforcing the boundary, not just present in the schema.
Accomplishments that we're proud of
- A blockade that holds for an entire session against a user actively trying to reopen a blocked app, verified against real running processes.
- Scheduling that correctly fires multiple moods in the same minute and never double-fires across a minute rollover.
- An polished app that is genuinely indistinguishable, from any other app, down to its icon and process name.
What we learned
Environmental automation lives or dies on its edge cases, not its happy path: what happens across a day boundary, what happens when two schedules collide, what happens when the "off" state of a feature runs at the same time as the "on" state of another. The features that felt hardest to build weren't the hardware integrations — Hue and Spotify APIs are well-documented — they were the small state-machine questions underneath: who owns the truth about what's currently running, and what does "off" really mean when three different triggers can turn something on.
What's next for Monolith
- More integrations beyond Hue and Spotify, such as smart thermostats, other lighting ecosystems
- Shared/team moods, so a household or a team can define a mood once and everyone opts in
- A public API so third-party automations can trigger a mood engage/disengage the same way the tray and hotkey do today
Log in or sign up for Devpost to join the conversation.