RAM & CPU temperature monitor for macOS. Lives in your menu bar. Zero bloat.
Download · Features · Build from Source · Auto-Update · Contributing
Therma gives you a permanent, low-overhead view of your Mac's memory and thermals — right in the menu bar. No subscription, no analytics, no Electron, no bloat.
Memory 63% · CPU 54°C
That's it. One line. Always there.
- Live RAM usage % and/or CPU temperature in the status bar
- Adjustable icon size, text size, and display mode (RAM · CPU · Both)
- 35 built-in color themes — Amber, Arctic, Cosmic, Matrix, Lava, and more
- Used / free / wired / compressed breakdown
- Memory pressure ring with gradient stroke
- One-click RAM purge — sends memory pressure signal to encourage apps to release caches
- Deep Clean — clears Xcode DerivedData, Gradle, JetBrains caches + purge
- Real-time per-sensor readings via IOKit / SMC (Apple Silicon & Intel)
- Color-coded thermal zones: 🔵 cool → 🟢 normal → 🟡 warm → 🟠 hot → 🔴 critical
- Historical bar chart (last 20 readings)
- Local notifications when RAM or CPU crosses your custom threshold
- 5-minute cooldown to prevent notification spam
- Launch at Login via ServiceManagement
- Temperature unit: °C or °F
- In-app updates via GitHub Releases — one click, no appcast server needed
| macOS | 14.0 Sonoma or later |
| Architecture | Apple Silicon (arm64) |
| Build tools | Xcode Command Line Tools (for source builds) |
- Go to Releases
- Download
Therma-<version>.zip - Unzip → drag Therma.app to
/Applications - Open Therma and grant the accessibility permission if prompted
brew install --cask therma# Clone
git clone https://github.com/jayzzjay98-stack/Therma.git
cd Therma
# Build, bundle, and install to /Applications
bash install.shThe install.sh script:
- Compiles a release binary via Swift Package Manager
- Assembles the
.appbundle withInfo.plistandAppIcon.icns - Copies the bundle to
/Applications/Therma.app - Registers a Login Item and launches the app
Run tests:
swift test
# → 65 tests, 0 failuresRegenerate the app icon:
bash scripts/build_icon.sh
# Draws a 1024×1024 PNG with NSBezierPath → sips → iconutil → AppIcon.icnsTherma updates itself from GitHub Releases with no external server needed.
For users: Settings → About → Check for Updates → Download → Install & Relaunch
For maintainers — publishing a release:
# 1. Bump CFBundleShortVersionString in Info.plist (e.g. "1.1")
# 2. Build and verify a clean release zip
bash scripts/build_release_zip.sh
# 3. Create a GitHub Release tagged vX.Y.Z and attach the zip from dist/
gh release create v1.1 dist/Therma-1.1.zip \
--title "Therma 1.1" \
--notes "What changed."The release script creates a zip named Therma-<version>.zip, keeps Therma.app at the archive root, strips update-breaking metadata, applies ad-hoc signing, and runs the updater dry-run verifier before you upload the asset.
Therma/
├── Sources/Therma/
│ │
│ ├── ThermaApp.swift # @main — app entry point
│ ├── AppContext.swift # Shared singletons (monitors, prefs, updater)
│ ├── StatusBarController.swift # Menu bar item, popover, right-click menu
│ │
│ ├── RAMMonitor.swift # Memory stats via Mach host_statistics64
│ ├── CPUMonitor.swift # Temperatures via IOKit / SMC
│ ├── CPUSensorPolicy.swift # Sensor ranking & selection
│ ├── MemoryStatsProvider.swift # vm_statistics64 abstraction
│ │
│ ├── MenuBarView.swift # SwiftUI popover root
│ ├── MenuBarComponents.swift # CPU cards, stat boxes, history bars
│ ├── MenuBarLabel.swift # Status bar text rendering
│ │
│ ├── SettingsView.swift # Settings window (sidebar layout)
│ ├── SettingsViewComponents.swift # Sidebar items, pref rows, sliders
│ ├── MenuBarPreferences.swift # All preferences (UserDefaults-backed)
│ ├── LayoutMetrics.swift # Window & layout constants
│ ├── ThemeRegistry.swift # 35 built-in color themes
│ │
│ ├── UpdateManager.swift # GitHub Releases auto-updater
│ ├── AlertManager.swift # UNUserNotificationCenter alerts
│ ├── PurgeManager.swift # Privileged RAM purge
│ ├── CacheManager.swift # Developer cache sweep
│ │
│ ├── ProcessManager.swift # Top-process listing
│ ├── ProcessCore.swift
│ ├── ProcessProtectionPolicy.swift
│ ├── ProcessSnapshotReader.swift
│ ├── LeftoverProcessDetector.swift
│ ├── AppLifecycleTracker.swift
│ │
│ ├── ChipDetector.swift
│ ├── LaunchAtLoginManager.swift
│ ├── MonitorDisplayMode.swift
│ └── Constants.swift
│
├── Tests/ThermaTests/ # 65 unit tests
│
├── scripts/
│ ├── generate_app_icon.swift # Programmatic icon (NSBezierPath)
│ └── build_icon.sh # PNG → iconset → .icns
│
├── .github/workflows/ci.yml # Build + test on every push / PR
│
├── install.sh # Build + install to /Applications
├── uninstall.sh # Remove app, sudoers rule, login item
├── create_dmg.sh # Package a release DMG
├── notarize.sh # Apple notarization workflow
├── Info.plist
├── Package.swift
└── AppIcon.icns
| Permission | Reason |
|---|---|
| Accessibility | Reading CPU temperature sensors via IOKit |
| Notifications | RAM / CPU threshold alerts |
| Login Items | Launch at login (off by default) |
Therma makes no network requests except when you explicitly click Check for Updates.
Every push and pull request to main runs the full test suite via GitHub Actions (.github/workflows/ci.yml):
- Debug build + 65 unit tests
- Release binary (arm64) on
mainpushes - DMG artifact uploaded to workflow artifacts
- Fork the repo and create a branch:
git checkout -b feature/my-change - Make your changes
- Run
swift test— all 65 tests must pass - Commit with a Conventional Commit message
- Open a pull request
Bug reports and feature ideas are welcome via Issues.
MIT © 2025 jayzzjay98-stack