Duck's up, all night baby.
Free Mac menu-bar app. Two ways to use it. Both start with "close the lid":
- Keep your Mac awake β on battery, lid shut. Long LLM runs, renders, overnight downloads. The only Mac sleep blocker that survives Apple Silicon firmware in that scenario.
- MacBook as Mac mini on the go. Your M-series laptop is a Mac mini with a battery. Close the lid, dock it, run Ollama / a home server / whatever. macOS used to refuse. Duck makes it stop.
Duck walks when you do. Duck mildly judges you. That's the rest of it.
A hotel room in Vienna, layover night. Looking out the window at the Danube.
Ducks on the water, doing duck things.
The captain calls. "Bro, come hang out."
I want to go. But my LLM is running β and apparently planning to
take over my job.
You know the captain doesn't wait.
So I Close the lid. Walk out.
Duck!! (I yelled)
LLM died (not everyone want to effort Mac mini you know)
Render gone. Hours of work, gone.
I sat back down by the window. Looked at the river.
Looked at the ducks.
That's the night the duck rose. Up and all night, baby.
You close the lid. Mac sleeps.
Duck's up. Mac No sleeps.
(details? β all explanation below for the nerds)
-
One button. Click duck standing upright to the sky. Click duck again sad and fat.
-
A walking duck. YES, walking duck. (Duck around and find out.)
-
Don't Die. The duck don't duck your Mac battery when below 5%
(BJ can not save it either β Bryan Johnson, I mean)
-
Four skins. Classic, Rubber, Charcoal, Mono. More if you tip the duck.
-
No snitching. No telemetry, no accounts, no network.
getstayup.app β download the DMG, drag the duck to Applications, double-click. Done.
Tip
macOS throws a few dialogs on first launch. None are the duck being sneaky:
- Welcome window β tick Launch at Login + Set up Helper for full beast mode.
- Helper setup β macOS asks once, then a password prompt. Helper talks to
pmsetas root. Both normal. - Sparkle prompt (2nd launch) β opt in for auto-updates. Pings
appcast.xmlonly when you say yes. Nothing else.
git clone https://github.com/NongKnot/StayUp.git
cd StayUp
bash build.sh
cp -r StayUp.app /Applications/
open /Applications/StayUp.appFor full beast mode β Settings β Helper β Set up. Same prompts as
the lazy way. No sudo, no installer β helper lives inside the bundle,
registered via SMAppService.
Free forever. The features stay free forever.
Duck has rent.
If the duck saved your AI / render / overnight download from the
closed-lid massacre β π Feed the Duck (in settings) or visit
getstayup.app/tip.
For most users, the polite teardown is two clicks + one drag:
- Open the duck β Settings β Helper β Uninstall Helper. Sends
disableto the daemon sopmset disablesleep 0runs cleanly, waits for the drain, then unregisters the daemon viaSMAppService.unregister()β the right macOS API for this. A confirmation alert appears before the uninstall fires. - Drag
/Applications/StayUp.appto the Trash.
That's it. macOS removes the Login Items entry on the next system check.
For the impatient duck haver who wants it gone right now:
# Quit the duck.
pkill -x StayUp
# Stop the daemon (doesn't remove the Login Items entry).
sudo launchctl bootout system/app.getstayup.helper
# Drop the bundle.
rm -rf /Applications/StayUp.app
# (Optional) Wipe preferences.
defaults delete app.getstayupIf rm -rf left a ghost entry in System Settings β General β Login
Items & Extensions β Allow in the Background, toggle it off and hit
the β button to remove it fully. (launchctl bootout unloads the
running daemon but doesn't delete the SMAppService registration β
that's a quirk of the macOS API, not a StayUp bug. The Settings β
Helper β Uninstall Helper path above uses the right API and doesn't
leave a ghost.)
StayUp also self-heals stale helper registrations on next launch: if you skip the teardown and just reinstall the bundle, the app detects the dangling registration and silently re-points it at the new bundle. So the most common reinstall path (drag the new DMG over the old one) just works.
Duck doesn't snitch.
- No telemetry. No analytics. No crash reporting (sorry).
- No accounts.
- One network call: Sparkle asks
getstayup.app/appcast.xmlfor a newer duck β only if you opt in. EdDSA-signed; compromised CDN can't ship a backdoored DMG. - Accelerometer reads stay local. Only while engaged. Dropped after each sample.
Normal human β don't give a duck about this. Close the tab.
Nerd human β five layers fire when you click. None redundant (OK, a bit. Cost is low so duck it). Each one covers a different way macOS tries to sleep on you.
| # | Layer | Trick | File |
|---|---|---|---|
| 1 | Caffeinate |
caffeinate -dis -w $PID subprocess |
Sources/Caffeinate.swift |
| 2 | SleepPreventer |
IOKit idle/display assertions + ProcessInfo activity | Sources/SleepPreventer.swift |
| 3 | ClosedLidPreventer |
kIOPMAssertionTypePreventSystemSleep (clamshell on AC) |
Sources/ClosedLidPreventer.swift |
| 4 | VirtualDisplay |
Private CGVirtualDisplay β fake external monitor |
Sources/VirtualDisplay.swift |
| 5 | StayUpHelper |
Root daemon + Unix socket β pmset disablesleep |
Sources/StayUpHelper.swift + Helper/main.swift |
Battery + lid closed: only layers 4 and 5 survive the Apple Silicon firmware override (Ventura+).
Together, duck stays up.
For the walk: duck just walks. Yea.
Icons are all Core Graphics β no GIFs, no asset bundles. Animation system ~250 lines, cached frames ~8 MB RAM steady state.
Measured on shipping v1.0, Apple Silicon, macOS 26. RAM = physical
footprint (the number Activity Monitor shows in the Memory column,
not ps RSS which inflates by ~80 MB of shared framework code that's
mapped read-only into every process):
| State | CPU | RAM |
|---|---|---|
| Idle (engaged: OFF) | ~0.1% | ~37 MB |
| Active (engaged: ON) | ~0.1% | ~37 MB |
| Walking (accelerometer live at 14 Hz) | 1β3% bursts at stride detection | ~37 MB |
That's the Cocoa-app floor. An empty AppKit menu-bar app with just an
NSStatusItem is already ~25β30 MB. The 5-layer engine + walk detector
- Sparkle + settings panel + helper IPC adds ~7 MB on top.
Most "always on" menu-bar apps poll forever. Duck doesn't. Accelerometer only powers on when engaged. Battery polling only when engaged. Don't Die idles. Idle CPU is effectively zero.
| Disk footprint | Size |
|---|---|
| App bundle | 3.8 MB |
| Sparkle.framework (auto-updater) | 3.0 MB |
| StayUp binary itself | 596 KB |
| Notarized DMG (compressed) | 1.5 MB |
Good question.
Duck story time
Duck googled "keep mac awake lid closed battery."
First result:
amphetamine. The drug.
Duck closed the tab. Felt judged. Moved on. Duck pond no Drug Zone.
Duck also stupid enough to make the whole app to use alone by itself
for whatever Duck reason.
Later Duck found out Amphetamine
is also a beloved free Mac app β the original one, by William C. Gustafson.
Big respect. Been keeping Macs awake since forever.
Duck tried it. Worked great for most things. But for the specific
battery + lid closed case, it didn't quite click the way Duck wanted.
You install the separate Amphetamine Power Protect
helper alongside it, and the trick is to keep the internal display on
with the lid down.
So Duck goes the other way β pretends to plug in an external display
(CGVirtualDisplay) and lets the internal one go to sleep.
Both work. Different way.
- Claude by Anthropic β co-developed this whole thing alongside the human normie.
- Claude Design β duck mascot.
- BetterDummy by Istvan T.
- olvvier/apple-silicon-accelerometer by Olivier Bourbonnais
- OxWearables/stepcount
/usr/bin/caffeinateβ Apple's own sleep-prevention tool.
Side project. Duck has a day job (looking serious in a menu bar). Issues + PRs welcome. No SLA. Best effort.
If you fork: don't reuse the StayUp name or duck artwork. MIT covers code, not brand. Make your own bird.
MIT. See LICENSE. Brand and mascot not included.
π¦ stays up so you don't have to



