# navtoj/notchbar architecture

> Architecture diagram of the GitHub repository navtoj/notchbar, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-19). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/navtoj/notchbar
- Repository: https://github.com/navtoj/notchbar

## Overview

1. **What this repository is**
   - NotchBar is a **macOS 14.5+ SwiftUI app** that overlays custom content in the unused area around a MacBook notch and also exposes a small menu bar item for actions.

2. **Top-level architecture**
   - The app is organized as a **single macOS application target** under `src/NotchBar`, built with **Tuist** (`src/Project.swift`, `src/Tuist.swift`, `src/Tuist/Package.swift`).
   - Source is split into clear layers: app bootstrap, shared state, window/UI composition, reusable widget modules, shapes/visual helpers, and small extensions.

3. **App lifecycle and bootstrap**
   - `main.swift` is the entry point.
   - `AppDelegate.swift` and `AppWindow.swift` likely handle macOS-specific app startup concerns that SwiftUI alone does not cover well: creating the main overlay window, controlling visibility, and coordinating app/menu-bar behavior.
   - `AppView.swift` is the top-level SwiftUI view that composes the main notch-bar interface.

4. **Core state boundary**
   - `AppState.swift` and `SystemState.swift` form the app’s state layer.
   - This is the primary boundary between UI and live system data: the UI reads from state objects, while system polling/observation updates them.
   - `AppUrls.swift` centralizes app-specific navigation or external links used by settings/help actions.

5. **Widget architecture**
   - The `Sources/Widgets` folder is the main feature subsystem.
   - `WidgetView.swift` acts as a generic wrapper for a widget with:
     - a **primary view** that is always visible in the notch bar,
     - an optional **secondary view** used for a dropdown/details card.
   - This gives the app a reusable pattern for multiple widget types without duplicating layout logic.

6. **Concrete widgets shipped in the repo**
   - `ActiveApp` shows the currently focused app’s icon/name.
   - `MediaRemote` displays media playback data and controls; it has both primary and secondary views and a `MediaCommand` model for user actions.
   - `SystemInfo` shows system-monitor style information such as CPU, memory, storage, battery, and network.
   - `Example` provides sample widget views and serves as a reference implementation/template.

7. **Data flow from system sources to UI**
   - Widget-specific data models (`ActiveAppData`, `MediaData`, `SystemInfoData`) represent the live snapshot each widget renders.
   - System-facing helpers and extensions (`SystemInfoExtension.swift`, `MediaCommand.swift`) adapt platform APIs into the app’s internal data flow.
   - The general flow is: **macOS/system APIs → widget data structs/state → SwiftUI widget views → overlay/menu-bar presentation**.

8. **Windowing and layout**
   - `WindowViews/Settings.swift` and `WindowViews/Welcome.swift` are separate window-level screens, distinct from the always-visible notch-bar content.
   - This suggests the app uses a mix of **main overlay window** plus auxiliary windows/sheets for onboarding and configuration.
   - `Shapes/` contains custom geometry used to fit the display notch and rounded edges precisely:
     - `InvertedCapsule`
     - `InvertedBottomCorners`
     - `RoundCornersInvertedTop`

9. **UI helpers and platform extensions**
   - The `Extensions/` folder contains small cross-cutting helpers for `Angle`, `NSColor`, `NSImage`, `NSScreen`, `UserDefaults`, and `View`.
   - These are likely used to bridge AppKit and SwiftUI, inspect screen geometry, persist preferences, and tweak rendering behavior.
   - `External/Marquee.swift` is a vendored UI utility for scrolling text, probably used where widget content must fit tight horizontal space.

10. **Resources and assets**
   - App icons and color assets live under `Resources/Assets.xcassets`.
   - The `_assets` folder is documentation/marketing content for the README, including screenshots and installation imagery; it is not part of runtime app logic.

11. **Build, packaging, and release**
   - Tuist manages project generation and dependency resolution.
   - `.github/workflows/release.yml` indicates an automated release pipeline that likely builds, packages, and publishes the distributable `.zip`/`.app` used by the README installation flow.
   - The repo is therefore designed around **source-managed app generation + release artifact distribution**, not server deployment.

12. **Architecture summary for a diagram**
   - The cleanest diagram is: **macOS app shell** in the center, fed by **system/app state sources**, rendering through **SwiftUI widget modules**, with **custom notch-shaped window geometry** and **secondary settings/welcome windows**, all built and packaged via **Tuist + GitHub Actions**.

Main entry points: [`src/NotchBar/Sources/AppView.swift`](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppView.swift) (App view), [`src/NotchBar/Sources/Widgets/MediaRemote/MediaPrimary.swift`](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaPrimary.swift) (Media remote), [`src/NotchBar/Sources/Widgets/WidgetView.swift`](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/WidgetView.swift) (Widget view), [`src/NotchBar/Sources/AppDelegate.swift`](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppDelegate.swift) (App delegate)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_app["App shell"]
  node_node_main(("main<br/>entrypoint<br/>[main.swift]"))
  node_node_delegate["App delegate<br/>lifecycle<br/>[AppDelegate.swift]"]
  node_node_window["App window<br/>windowing<br/>[AppWindow.swift]"]
  node_node_appview["App view<br/>root view<br/>[AppView.swift]"]
  node_node_appstate[("App state<br/>shared state<br/>[AppState.swift]")]
  node_node_systemstate[("System state<br/>system model<br/>[SystemState.swift]")]
  node_node_urls["App URLs<br/>navigation<br/>[AppUrls.swift]"]
  node_node_settings["Settings<br/>window screen<br/>[Settings.swift]"]
  node_node_welcome["Welcome<br/>window screen<br/>[Welcome.swift]"]
end

subgraph group_group_widgets["Widgets"]
  node_node_widgetview["Widget view<br/>widget shell<br/>[WidgetView.swift]"]
  node_node_activeapp_data[("Active app data<br/>widget model")]
  node_node_activeapp["Active app<br/>widget"]
  node_node_media_data[("Media data<br/>widget model<br/>[MediaData.swift]")]
  node_node_media_cmd["Media command<br/>action model<br/>[MediaCommand.swift]"]
  node_node_media["Media remote<br/>widget<br/>[MediaPrimary.swift]"]
  node_node_media_secondary["Media details<br/>widget panel"]
  node_node_sysinfo_data[("System info data<br/>widget model")]
  node_node_sysinfo_ext["System info ext<br/>platform adapter"]
  node_node_sysinfo["System info<br/>widget"]
  node_node_example_primary["Example primary<br/>sample widget<br/>[PrimaryView.swift]"]
  node_node_example_secondary["Example secondary<br/>sample widget"]
end

subgraph group_group_ui["UI support"]
  node_node_shapes{{"Notch shapes<br/>geometry"}}
  node_node_extensions["Extensions<br/>helpers"]
  node_node_marquee["Marquee<br/>vendored ui<br/>[Marquee.swift]"]
  node_node_helpers["Helpers<br/>[Helpers.swift]"]
end

subgraph group_group_build["Build & release"]
  node_node_project["Project<br/>tuist config<br/>[Project.swift]"]
  node_node_tuist["Tuist<br/>[Tuist.swift]"]
  node_node_package["Package manifest<br/>swiftpm<br/>[Package.swift]"]
  node_node_release["Release CI<br/>workflow<br/>[release.yml]"]
end

node_node_main -->|"starts"| node_node_delegate
node_node_delegate -->|"creates"| node_node_window
node_node_delegate -->|"owns"| node_node_appstate
node_node_appview -->|"composes"| node_node_widgetview
node_node_appview -->|"opens"| node_node_settings
node_node_appview -->|"opens"| node_node_welcome
node_node_systemstate -->|"feeds"| node_node_appstate
node_node_appstate -->|"drives"| node_node_appview
node_node_urls -.->|"links"| node_node_appview
node_node_widgetview -->|"wraps"| node_node_activeapp
node_node_widgetview -->|"wraps"| node_node_media
node_node_widgetview -->|"wraps"| node_node_sysinfo
node_node_activeapp -->|"reads"| node_node_activeapp_data
node_node_media -->|"reads"| node_node_media_data
node_node_media -->|"acts on"| node_node_media_cmd
node_node_media -->|"expands to"| node_node_media_secondary
node_node_sysinfo -->|"reads"| node_node_sysinfo_data
node_node_sysinfo_ext -->|"adapts"| node_node_sysinfo_data
node_node_example_primary -.->|"pairs with"| node_node_example_secondary
node_node_shapes -->|"fits"| node_node_window
node_node_extensions -.->|"supports"| node_node_window
node_node_extensions -.->|"supports"| node_node_appview
node_node_marquee -.->|"used by"| node_node_media
node_node_helpers -.->|"supports"| node_node_appview
node_node_project -->|"configures"| node_node_tuist
node_node_tuist -->|"resolves"| node_node_package
node_node_release -->|"builds"| node_node_project
node_node_release -.->|"packages"| node_node_package

click node_node_main "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/main.swift"
click node_node_delegate "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppDelegate.swift"
click node_node_window "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppWindow.swift"
click node_node_appview "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppView.swift"
click node_node_appstate "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppState.swift"
click node_node_systemstate "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/SystemState.swift"
click node_node_urls "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppUrls.swift"
click node_node_widgetview "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/WidgetView.swift"
click node_node_activeapp_data "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppData.swift"
click node_node_activeapp "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppPrimary.swift"
click node_node_media_data "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaData.swift"
click node_node_media_cmd "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaCommand.swift"
click node_node_media "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaPrimary.swift"
click node_node_media_secondary "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaSecondary.swift"
click node_node_sysinfo_data "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoData.swift"
click node_node_sysinfo_ext "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoExtension.swift"
click node_node_sysinfo "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoPrimary.swift"
click node_node_example_primary "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/Example/PrimaryView.swift"
click node_node_example_secondary "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/Example/SecondaryView.swift"
click node_node_settings "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/WindowViews/Settings.swift"
click node_node_welcome "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/WindowViews/Welcome.swift"
click node_node_marquee "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/External/Marquee.swift"
click node_node_helpers "https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Helpers.swift"
click node_node_project "https://github.com/navtoj/notchbar/blob/main/src/Project.swift"
click node_node_tuist "https://github.com/navtoj/notchbar/blob/main/src/Tuist.swift"
click node_node_package "https://github.com/navtoj/notchbar/blob/main/src/Tuist/Package.swift"
click node_node_release "https://github.com/navtoj/notchbar/blob/main/.github/workflows/release.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_main,node_node_delegate,node_node_window,node_node_appview,node_node_appstate,node_node_systemstate,node_node_urls,node_node_settings,node_node_welcome toneBlue
class node_node_widgetview,node_node_activeapp_data,node_node_activeapp,node_node_media_data,node_node_media_cmd,node_node_media,node_node_media_secondary,node_node_sysinfo_data,node_node_sysinfo_ext,node_node_sysinfo,node_node_example_primary,node_node_example_secondary toneAmber
class node_node_shapes,node_node_extensions,node_node_marquee,node_node_helpers toneMint
class node_node_project,node_node_tuist,node_node_package,node_node_release toneRose
```

## Components

### App shell

macOS app lifecycle, state, and window composition

- [main](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/main.swift): entrypoint · App entry point · `src/NotchBar/Sources/main.swift`
- [App delegate](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppDelegate.swift): lifecycle · macOS startup and menu bar coordination · `src/NotchBar/Sources/AppDelegate.swift`
- [App window](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppWindow.swift): windowing · Overlay window management · `src/NotchBar/Sources/AppWindow.swift`
- [App view](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppView.swift): root view · Top-level SwiftUI composition · `src/NotchBar/Sources/AppView.swift`
- [App state](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppState.swift): shared state · UI-facing application state · `src/NotchBar/Sources/AppState.swift`
- [System state](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/SystemState.swift): system model · Live system data boundary · `src/NotchBar/Sources/SystemState.swift`
- [App URLs](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/AppUrls.swift): navigation · App links and destinations · `src/NotchBar/Sources/AppUrls.swift`
- [Settings](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/WindowViews/Settings.swift): window screen · Configuration window · `src/NotchBar/Sources/WindowViews/Settings.swift`
- [Welcome](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/WindowViews/Welcome.swift): window screen · Onboarding window · `src/NotchBar/Sources/WindowViews/Welcome.swift`

### Widgets

Reusable notch-bar widgets and their data models

- [Widget view](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/WidgetView.swift): widget shell · Generic primary/secondary widget wrapper · `src/NotchBar/Sources/Widgets/WidgetView.swift`
- [Active app data](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppData.swift): widget model · Focused app snapshot · `src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppData.swift`
- [Active app](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppPrimary.swift): widget · Focused app widget · `src/NotchBar/Sources/Widgets/ActiveApp/ActiveAppPrimary.swift`
- [Media data](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaData.swift): widget model · Playback snapshot · `src/NotchBar/Sources/Widgets/MediaRemote/MediaData.swift`
- [Media command](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaCommand.swift): action model · Media control actions · `src/NotchBar/Sources/Widgets/MediaRemote/MediaCommand.swift`
- [Media remote](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaPrimary.swift): widget · Playback widget with details card · `src/NotchBar/Sources/Widgets/MediaRemote/MediaPrimary.swift`
- [Media details](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/MediaRemote/MediaSecondary.swift): widget panel · Expanded media controls and info · `src/NotchBar/Sources/Widgets/MediaRemote/MediaSecondary.swift`
- [System info data](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoData.swift): widget model · System monitor snapshot · `src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoData.swift`
- [System info ext](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoExtension.swift): platform adapter · System API adaptation · `src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoExtension.swift`
- [System info](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoPrimary.swift): widget · System metrics widget · `src/NotchBar/Sources/Widgets/SystemInfo/SystemInfoPrimary.swift`
- [Example primary](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/Example/PrimaryView.swift): sample widget · Reference primary widget view · `src/NotchBar/Sources/Widgets/Example/PrimaryView.swift`
- [Example secondary](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Widgets/Example/SecondaryView.swift): sample widget · Reference secondary widget view · `src/NotchBar/Sources/Widgets/Example/SecondaryView.swift`

### UI support

Shapes, helpers, extensions, and vendored UI utilities

- **Notch shapes**: geometry · Custom display-notch fitting shapes
- **Extensions**: helpers · Cross-cutting Swift/AppKit extensions
- [Marquee](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/External/Marquee.swift): vendored ui · Scrolling text utility · `src/NotchBar/Sources/External/Marquee.swift`
- [Helpers](https://github.com/navtoj/notchbar/blob/main/src/NotchBar/Sources/Helpers.swift): shared helpers · Common utilities · `src/NotchBar/Sources/Helpers.swift`

### Build & release

Project generation and release automation

- [Project](https://github.com/navtoj/notchbar/blob/main/src/Project.swift): tuist config · Tuist project definition · `src/Project.swift`
- [Tuist](https://github.com/navtoj/notchbar/blob/main/src/Tuist.swift): tuist config · Tuist setup and dependencies · `src/Tuist.swift`
- [Package manifest](https://github.com/navtoj/notchbar/blob/main/src/Tuist/Package.swift): swiftpm · Swift package dependencies · `src/Tuist/Package.swift`
- [Release CI](https://github.com/navtoj/notchbar/blob/main/.github/workflows/release.yml): workflow · Automated release pipeline · `.github/workflows/release.yml`

## Connections

- main → App delegate: starts · Entrypoint hands off to app lifecycle
- App delegate → App window: creates · Delegate manages overlay window lifecycle
- App delegate → App state: owns · Delegate initializes shared app state
- App view → Widget view: composes · Root view uses reusable widget wrapper
- App view → Settings: opens · UI can present settings window
- App view → Welcome: opens · UI can present onboarding window
- System state → App state: feeds · System observations update app-facing state
- App state → App view: drives · State changes update top-level UI
- App URLs → App view: links · Navigation/help destinations used by UI
- Widget view → Active app: wraps · Generic shell hosts active app widget
- Widget view → Media remote: wraps · Generic shell hosts media widget
- Widget view → System info: wraps · Generic shell hosts system info widget
- Active app → Active app data: reads · Renders focused app snapshot
- Media remote → Media data: reads · Renders playback snapshot
- Media remote → Media command: acts on · User controls map to media commands
- Media remote → Media details: expands to · Primary widget opens detail panel
- System info → System info data: reads · Renders system metrics snapshot
- System info ext → System info data: adapts · Platform APIs normalized into widget data
- Example primary → Example secondary: pairs with · Example widget shows primary/secondary pattern
- Notch shapes → App window: fits · Custom geometry supports notch-shaped windowing
- Extensions → App window: supports · Geometry, color, image, and screen helpers
- Extensions → App view: supports · Shared view and persistence helpers
- Marquee → Media remote: used by · Scrolling text for tight widget layouts
- Helpers → App view: supports · Shared utilities used across UI
- Project → Tuist: configures · Project generation setup
- Tuist → Package manifest: resolves · Tuist depends on package manifest
- Release CI → Project: builds · CI releases the generated app artifact
- Release CI → Package manifest: packages · Release pipeline uses Swift package dependencies
