Skip to content
egemertbalcikPublic

About

Free, open-source notch app for MacBook: turns the Mac notch into a Dynamic Island-style live status area with now playing, a focus timer, your next meeting with a camera mirror, weather, notes, Keep Awake (lid closed too), AirPods battery and a volume and brightness HUD. macOS 26+. Your MacBook's notch, put to work.

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Repository files navigation

Ledge

Your MacBook's notch, put to work.

Ledge is a free, open-source notch app for MacBook on macOS 15 or later.

You already look up there. Ledge puts what you're checking anyway — the song, the timer, the next meeting — in the black bar you've been ignoring so far. Quiet when nothing is happening, there the moment something is.

Download Ledge, the notch app for MacBook Buy me a coffee

ledgeapp.dev · free · open source · no account

Latest release macOS 15 or later Install with Homebrew: brew install --cask egemertbalcik/tap/ledge License: GPL-3.0

Ledge waking up in the MacBook notch
ledge-film-readme.mp4

What is Ledge? Ledge is a free, open-source (GPL-3.0) notch app for MacBook. It turns the notch into a live status area, like the iPhone's Dynamic Island: now playing, a timer, your next meeting with a camera mirror on the Join button, weather, notes, Keep Awake (lid closed too), AirPods battery, plus volume and brightness readouts. It needs a MacBook with a notch on macOS 15 or later. It ships signed and notarized, has no account or telemetry and records no audio or screen.


Skip a track without losing your place

Cover art, the title, the scrub bar, the buttons. Send the sound to your AirPods from the same card. Works with Music, with Spotify, and with whatever tab is playing in your browser.

Music resting in the notch, the card opening under the pointer and skipping to the next song, then the volume going up in place of the right ear

Your day, one glance up

What's next, and the month it belongs to. The weather where you are, and the hours coming. When a meeting is about to start, the Join button grows a little mirror: one click and your camera opens in the card, so you can fix your hair before anyone else sees it. Choose which calendars show, account by account, in Settings.

A meeting four minutes away in the notch, the calendar card opening, Join with the camera, and the mirror going live Swiping through the cards that open from the notch: calendar, timer, weather, levels, AirPods and notes

Leave it working and walk away

Running a build, a long download, or an agent that needs another hour? Keep Awake holds the Mac and the screen on until you say stop. It's what caffeinate does, minus the terminal.

The Keep Awake card: Coffee, then Espresso, the dial set to two hours, and Keep awake pressed

Move it one stop further and the Mac keeps going with the lid shut. The screen, the keyboard light and the speakers go quiet so the battery goes to the work, and it all lets go at the time you set. That stop needs a small helper running as root. It's only installed when you turn it on, and it's removed when you turn it off. Keep Awake itself stays out of the way until you switch it on in Settings.

Write it down before it's gone

A phone number, a command, the thing you'll forget in ten minutes. Notes keeps your five most recent on a card, and opens each one in its own window when there's more to say. They're plain files on your Mac, and any of them can go to Apple Notes in one click.

Opening Notes from the notch, a new note in its own window, typing with Caps Lock on, then closing it

Show anything a script can write

Feeds turn small files into cards. Put a JSON file in ~/Library/Application Support/Ledge/Feeds/ and Ledge shows it as a card with a title, a few rings across the top and a few rows under them, and, if the file asks, a short reading on either side of the notch while it's closed. A build's status, a backup's last run, a quota, a queue length: whatever a script can write down. Ledge only reads these files. It never runs anything.

Feeds are off until you switch them on in Settings, under Cards.

{
  "version": 1,
  "id": "usage",
  "title": "Usage",
  "symbol": "gauge.with.dots.needle.67percent",
  "compact_leading": "42%",
  "compact_leading_fraction": 0.42,
  "compact_trailing": "85%",
  "compact_trailing_fraction": 0.85,
  "level": "normal",
  "gauges": [
    {"label": "API", "value": "42%", "fraction": 0.42},
    {"label": "Storage", "value": "85%", "fraction": 0.85, "level": "warning"}
  ],
  "rows": [
    {"label": "Today", "value": "1.2k calls", "detail": "resets 05:00", "fraction": 0.42},
    {"label": "Last sync", "value": "02:14", "detail": "took 6 min"}
  ],
  "updated_at": 1794088196,
  "stale_after": 86400
}
Field
version Required, and 1. A file with another version is skipped.
id Optional, up to 128 characters. Defaults to the file name without .json.
title Optional, up to 80 characters. The card's title. Defaults to the id.
symbol Optional. The name of an SF Symbol.
compact_leading, compact_trailing Optional, up to 24 characters. Short text for the left and right of the notch while it's closed. Keep it to a few characters.
compact_leading_fraction, compact_trailing_fraction Optional. 0 to 1. Draws a small ring on that side, filled to the fraction, with the text drawn inside it, so keep that text to about four characters. With a fraction and no text, the ring is smaller and its colour follows the fraction, read as how much is left: green, orange under 40%, red under 15%. A level of warning makes it at least orange and critical makes it red. Without a fraction, the side shows the feed's symbol beside its text instead.
compact_leading_color, compact_trailing_color Optional. #RRGGBB. Fixes the colour of that side's ring and text, in place of the one level or the fraction would give it. A critical level still shows red, and a colour too dark to see on the black notch is brightened just enough.
level Optional. normal, warning or critical. Colours the closed notch's ring and text. A feed turning critical peeks once, and then not again for 30 minutes however often it goes back and forth.
gauges Optional. Up to four, shown as rings across the top of the card. Each needs a label (up to 20 characters), a short value that goes inside the ring (up to 12) and a fraction from 0 to 1, and may have a level (normal, warning or critical) that colours the ring, or a color (#RRGGBB) that fixes it, except that critical is always red. An item missing one of the three is skipped.
rows Optional. Up to eight, each with a label and a value (both required, up to 60 characters each), and optionally a detail (up to 80), a fraction from 0 to 1 that draws a thin bar, and a level.
updated_at Optional. Unix seconds. Defaults to when the file was last written. A time more than five minutes ahead of when Ledge first read the file isn't believed: the time the file was written is used instead.
stale_after Optional. Seconds after updated_at when the numbers stop being true. The card then dims and says how old it is.

Replace a file by writing a temporary file beside it and renaming it over the original, so Ledge never reads half of one. Fields it doesn't know are ignored, and longer text is cut to the limits above. A file that isn't valid JSON, is over 64 KB or has a version above 1 is skipped, with a line in the log; if it was readable before, its card keeps what it last said for two minutes, then dims as out of date. A feed's card goes when its file does. Ledge reads the first 16 files by name and leaves the rest unopened. Links aren't followed, so put the file itself in the folder.

The closed notch shows one feed's text at a time, and only while nothing else (music, a timer, a close meeting) is using it. The feed showing there keeps its place until it goes out of date or away; then the most recently updated feed with text takes over.

And the rest

Brightness changing, the readout in place of the right ear Caps Lock turning on and off over the music
A twenty-five minute countdown starting beside the music in the notch AirPods connecting, then a Focus mode turning on
The keyboard layout changing, then a low battery The charger plugged in, then the camera and microphone in use
Focus timer Start a session and the countdown sits at the edge of the notch while you work, close enough to glance at, too small to distract you.
Volume & brightness A readout in the notch that replaces macOS's own volume and brightness pop-up. Drag the bar to set the level, or click the speaker to mute.
AirPods & Bluetooth They connect, you see it — with battery, and the case animation you were promised on the iPhone.
Battery Where it stands, and a nudge while there's still time to do something about it.
Focus modes Tells you which mode just turned on. macOS barely mentions it.
File shelf Drop files on the notch, pull them out later. New screenshots land there by themselves.
Camera & mic A dot when something is recording, right where you're looking.
Caps Lock & keyboard layout Which one is on, without hunting for a menu bar flag.
Levels Sound and brightness as sliders on a card, for the keyboards and mice with no keys for it.

Every one of these can be switched off on its own. A source you turn off is never even built, so it does no work and asks for nothing.

What it will never do

Ledge records nothing: no screen or audio capture, nothing saved from the camera. The mirror opens when you press it and closes with the card. The equalizer that moves with your music is an animation; it never hears a note.

It stays out of your screenshots, recordings and shared screens, unless you want it in them.

Only four things go over the network: the weather (Open-Meteo, location rounded to about a kilometre), its place name (Apple), cover art, and the update check.

What it reaches for

Ledge does things macOS does not offer publicly, and you should know what before you install it.

It is not sandboxed, and it uses three private frameworks: DisplayServices for brightness, CoreBrightness to dim the keyboard light while the lid is shut, and MediaRemote to see what is playing in any app. Reading MediaRemote is not permitted to ordinary apps, so Ledge loads a small library of its own into /usr/bin/perl — a program Apple signs and entitles — and asks from there. That library does one thing, exports one symbol, and reports what is playing; nothing is written, and nothing else is touched. Every private symbol is looked up at runtime and checked, so when Apple removes one the feature quietly stops instead of the app crashing.

Accessibility, if you grant it, is used for one purpose: catching the volume and brightness keys so Ledge's readout can replace the system's rather than appear under it.

Keep Awake's lid-shut stop installs a helper that runs as root, because only root can stop a MacBook from sleeping when the lid closes. It holds the Mac awake on a 90-second lease that Ledge keeps renewing. If Ledge crashes, is force-quit or is updated mid-hold, the lease runs out and the Mac is free to sleep again. Nobody has to remember to undo it.

The consequences are real: this is software that can break on any macOS update, and it can never be sold on the App Store. The source for all of it is here.

Install

Download the DMG, drag Ledge into Applications, and open it from Finder — macOS gives the permissions to whatever launched the app, so starting it from a terminal hands them to the terminal instead. After that it checks for updates by itself with Sparkle and asks before installing one. You can install it, skip that version or be reminded later. There's also a Check for Updates… in Settings, under General.

There's no Dock icon — the notch is the app. The only time Ledge shows up in the menu bar is while it's holding the Mac awake with the lid shut, because once the lid is down the notch is out of reach. Open Ledge again from Finder or Spotlight and the copy that's already running brings its Settings up. Quitting is a button in there, under General.

Or with Homebrew:

brew install --cask egemertbalcik/tap/ledge

You'll need a MacBook with a notch — the 14- or 16-inch Pro from 2021, the Air from 2022 — on macOS 15 or later. Ledge draws on that display and nowhere else, on purpose: external monitors come in every shape, and a silhouette cut for the notch wouldn't be the same app on them.

Permissions

Nothing is asked for at launch. Each permission is requested by the one feature that needs it, from the Permissions tab in Settings — and everything else carries on without it.

Permission What it gives you If you say no
Accessibility Ledge's readout instead of the system one You get both, stacked
Automation Cover art and scrubbing in Music and Spotify, and sending a note to Apple Notes Music still shows up, just without the artwork; notes stay in Ledge
Calendars Your next event, and the month No calendar card
Camera The mirror on the Join button No mirror; Join still works
Bluetooth Connections the moment they happen, and AirPods proximity Still read, just a beat later
Focus status The notch says when a Focus is on, and stays quiet during it Announcements come through regardless
The Focus folder (optional, not a system permission) The Focus card follows the switch immediately, and names the mode Still shown, within a few seconds, as "Focus"
Location Weather for wherever you are Weather for a city you type in
Login Items (Keep Awake's helper) Keeping the Mac awake with the lid shut Awake still works, lid open

Build it yourself

git clone https://github.com/egemertbalcik/Ledge.git
cd Ledge
make run          # build, sign, launch

You'll need Swift 6.2 and an Apple Development signing identity. make test runs the suite, make lint checks the layer boundaries.

Written from scratch, with no code from any other project.

License

Copyright © 2026 Ege Mert Balçık. GPL-3.0 — see LICENSE. Fork it, learn from it, ship your own — as long as what you ship stays open too.


Made by Ege Mert Balçık · ledgeapp.dev
If Ledge earns its place in your notch, buy me a coffee.
Music in the film: “Ease Back” by Ketsa, licensed under CC BY 4.0; “Dance Robot ACTIVATE”, CC0.

About

Free, open-source notch app for MacBook: turns the Mac notch into a Dynamic Island-style live status area with now playing, a focus timer, your next meeting with a camera mirror, weather, notes, Keep Awake (lid closed too), AirPods battery and a volume and brightness HUD. macOS 26+. Your MacBook's notch, put to work.

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages