A lightweight macOS menu bar app that automatically tracks how you spend time on your computer. It runs quietly in the background, recording which apps you use, how much you type, and how long you spend in meetings or watching YouTube β then presents it all in a clean, dark-themed dashboard.
No cloud. No accounts. Everything stays local on your machine in a SQLite database.
Most time-tracking tools require manual input or send your data to external servers. Monitor takes a different approach:
- Fully automatic β no timers to start or stop, no manual categorization
- 100% local β your activity data never leaves your machine
- Zero config β install, grant Accessibility permission, and it just works
- Low overhead β runs in a worker thread, async I/O, no impact on typing or performance
Whether you want to understand your work habits, track how much time you spend coding vs. browsing, or just see if meetings are eating your day β Monitor gives you that visibility with no effort.
- App usage β tracks the active window every 5 seconds, recording app name, window title, and category
- Input activity β counts keystrokes and mouse clicks (aggregated counts only, no keylogging)
- Idle detection β automatically pauses tracking after 5 minutes of inactivity; resumes when you return
- Call detection β detects active calls in Zoom, Microsoft Teams, Google Meet, and FaceTime; suppresses idle detection during calls
- YouTube tracking β detects YouTube playing in any browser (12 browsers supported), even when the browser is not focused
- AI time tracking β tracks time spent with AI tools both as native apps and in browser tabs
- Project detection β extracts project names from IDE window titles (VS Code, Cursor, JetBrains, Zed, Sublime Text)
- Sleep/wake resilience β automatically recovers input and window tracking after macOS sleep cycles
Apps are automatically sorted into categories:
| Category | Examples |
|---|---|
| Coding | VS Code, Cursor, Xcode, JetBrains suite, Zed, Neovim, Sublime Text |
| Terminal | Terminal, iTerm2, Warp, Ghostty, Alacritty, kitty |
| AI | Claude, ChatGPT, Copilot, Ollama, Perplexity, Poe |
| Communication | Slack, Discord, Messages, Mail, Telegram, WhatsApp |
| Meetings | Zoom, Teams, FaceTime, Google Meet, Webex, Skype |
| Browsers | Chrome, Safari, Firefox, Arc, Brave, Edge, Vivaldi, Orion, Zen Browser |
| Productivity | Notion, Obsidian, Figma, Sketch, Office suite, Linear, Bear |
| DevTools | Postman, Docker, TablePlus, Tower, GitKraken, Proxyman |
| Entertainment | Spotify, YouTube, Music, Netflix, Twitch, VLC |
| System | System Settings, Activity Monitor, Disk Utility |
AI usage in browsers (Claude, ChatGPT, Gemini, Perplexity, Midjourney, Hugging Face, etc.) is automatically detected and categorized from window titles.
- Summary cards β active time, keystrokes, mouse clicks, call time, entertainment time, AI time
- Active time chart β hourly (today) or daily breakdown of active vs. idle time; click a bar to drill down
- Input activity chart β keystroke and click trends over time
- Categories doughnut β visual breakdown by category, click to drill down into individual apps
- Top apps β ranked bar chart of most-used applications, color-coded by category
- Project breakdown β top 10 coding projects extracted from IDE window titles
- AI time chart β daily breakdown by AI tool (Claude, ChatGPT, Perplexity, etc.)
- Call time chart β time spent in calls by service (Zoom, Teams, FaceTime, Google Meet)
- Entertainment chart β foreground entertainment apps plus background YouTube consumption
- Hour drill-down β click any hourly bar to see all apps active during that hour
- Day drill-down β click any daily bar to drill into that day's hourly breakdown
- Time range picker β today, this week, this month, or custom date range
- Auto-refresh β dashboard updates every 30 seconds while focused
- Tray icon with a quick-stats popup showing today's active time, keystrokes, clicks, call time, entertainment, AI time, and top app
- Pause/resume tracking with status indicator
- Open dashboard or quit from the tray
- Go to the Releases page
- Download Monitor.dmg (or the ZIP)
- Open the DMG and drag Monitor to your Applications folder
- Launch Monitor from Applications
On first launch, macOS will ask you to grant Accessibility permission:
- Go to System Settings β Privacy & Security β Accessibility
- Enable Monitor in the list
- macOS (Apple Silicon or Intel)
- Node.js 18+ and npm
- Python (for building native modules β usually pre-installed on macOS)
# Clone the repository
git clone https://github.com/NejcZdovc/monitor.git
cd monitor
# Install dependencies
npm install
# Run the app
npm startIn development mode the app appears as "Electron" in the Accessibility list. You may need to add it manually: Click + β navigate to
node_modules/electron/dist/Electron.appβ Open
| Command | Description |
|---|---|
npm start |
Run the app in development mode |
npm test |
Run the test suite (Jest) |
npm run package |
Package the app for distribution |
npm run make |
Create DMG and ZIP installers |
npm run lint |
Lint with Biome |
npm run typecheck |
Type-check with TypeScript |
npm run full-check |
Run lint, typecheck, and tests |
# Package the app
npm run package
# Create a DMG installer
npm run makeThe packaged app will appear in the out/ directory. The distributed version shows as "Monitor" in all system menus and uses the correct app icon.
Releases are published via a manual GitHub Actions workflow:
- Go to Actions β Publish β Run workflow
- Select the version bump type:
patch,minor, ormajor - Click Run workflow
The workflow bumps the version in package.json, creates a git tag, builds the app on macOS, and uploads ZIP and DMG artifacts as a GitHub Release. Go to the repo's Releases page to review and publish.
The app uses electron-updater to check for updates from GitHub Releases every 24 hours. Updates download silently in the background and install automatically when the user quits the app. Failed checks are retried up to 3 times with a 60-second delay.
Users can also check manually via the app menu (Monitor β Check for Updates...).
Note: Auto-updates on macOS require a code-signed build. Add
APPLE_ID,APPLE_PASSWORD, andAPPLE_TEAM_IDas repository secrets for notarization.
src/
βββ main/ # Electron main process (TypeScript)
β βββ main.ts # App entry point
β βββ auto-updater.ts # GitHub Releases auto-updater
β βββ tray.ts # Menu bar tray icon + popup
β βββ window-manager.ts # Dashboard window lifecycle
β βββ ipc-handlers.ts # IPC bridge between main β renderer
β βββ categories.ts # App β category mapping rules
β βββ constants.ts # Shared config (poll intervals, thresholds)
β βββ types.ts # Shared TypeScript types
β βββ data/
β β βββ database.ts # SQLite schema, migrations, orphan cleanup
β β βββ query-engine.ts # Dashboard read queries (prepared statements)
β β βββ activity-store.ts # Activity session writes
β β βββ input-store.ts # Input count writes
β β βββ call-store.ts # Call session writes
β β βββ background-entertainment-store.ts # YouTube session writes
β βββ tracking/
β βββ tracker-manager.ts # Orchestrates all trackers
β βββ window-tracker.ts # Active window polling (AppleScript)
β βββ input-tracker.ts # Keystroke/click aggregation (main thread)
β βββ input-worker.ts # Keystroke/click hooks (worker thread)
β βββ idle-detector.ts # System idle detection
β βββ call-detector.ts # Call process detection (pgrep)
β βββ youtube-tracker.ts # Background YouTube detection
β βββ session-lifecycle.ts # Reusable session open/split/close state machine
β βββ hour-split.ts # Hour-boundary splitting utilities
βββ renderer/
β βββ main_window/ # Dashboard UI
β β βββ index.html
β β βββ styles/main.css
β β βββ js/
β β βββ app.ts # Dashboard controller
β β βββ date-utils.ts
β β βββ format-utils.ts
β β βββ components/ # Chart components (Chart.js)
β βββ tray_popup/ # Tray quick-stats popup
β β βββ index.html
β β βββ styles/tray.css
β βββ preload.ts # Main window context bridge
β βββ tray-preload.ts # Tray popup context bridge
βββ assets/ # Icons, update manifest
βββ test/ # Jest test suite
- TypeScript β the entire codebase is TypeScript, built with Vite via electron-forge
- AppleScript for window titles β only requires Accessibility permission (not Screen Recording)
- Worker thread for input tracking β prevents keystroke hooks from blocking the main thread; auto-restarts after macOS sleep since IOKit event taps become invalid
- Hour-boundary splitting β all sessions are split at hour boundaries during tracking (not at query time), making hourly aggregation queries trivially correct
- Idle suppression during calls β idle detection is suppressed when Zoom, Teams, Google Meet, or FaceTime calls are active
- Retroactive idle timestamps β idle start is calculated retroactively (
now - idleSeconds) for accurate session boundaries - SQLite with WAL mode β fast, embedded, zero-config database using
better-sqlite3 - No frameworks β vanilla TypeScript frontend with Chart.js for visualization
- Biome for linting and formatting
Monitor is designed to be privacy-first:
- All data is stored locally in a SQLite database in your app data directory
- No network requests except update checks to GitHub Releases β no telemetry, no analytics
- Input tracking records counts only β it does not log what you type
- Window titles are stored locally for categorization β they are never transmitted
MIT