I Built a macOS Menu Bar App to Track My Freelance Time — Here's How

Published: (March 4, 2026 at 11:27 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

As a freelance developer juggling multiple clients, I had one recurring problem: I never really knew where my time was going.
I tried spreadsheets, Toggl, and “I’ll write it down later.” You know how that ends.

So I built my own macOS menu‑bar app – KronoBar 👋

What is KronoBar?

KronoBar is a lightweight macOS menu bar app that lets you log time entries per client and project without ever leaving your workflow. It lives quietly in your tray, one click away.

KronoBar screenshot showing today's entries with time split across clients

No account. No cloud. No subscription. Just a clean local app that minds its own business.

Why not just use an existing tool?

Most time trackers are either too heavy, too expensive, or require you to live inside a browser tab. I wanted something that:

  • Doesn’t interrupt my flow – a quick Cmd + Shift + T is all it takes
  • Stays local – all data lives on my machine (SQLite, no sync, no tracking)
  • Shows me the right info fast – today’s breakdown, weekly stats, nothing more

Features

  • 🎨 Color‑coded clients – see at a glance where your day went
  • 📅 Today / History / Stats views – browse by day, week, month, or year
  • 📤 CSV export – for invoicing or just your own records
  • ⌨️ Global shortcutCmd + Shift + T toggles the window from anywhere
  • 🌙 Dark mode – obviously
  • 🔒 100 % local – your data never leaves your machine

Tech stack

LayerTech
Desktop shellElectron + Electron Forge
UIReact + TypeScript
BuildVite
DatabaseSQLite via sql.js (WASM – zero native deps!)
StylingCSS Modules

The most interesting decision was using sql.js instead of a native SQLite binding. It runs SQLite compiled to WebAssembly, which means no native Node modules to deal with – packaging and distribution become much simpler.

The WASM SQLite trick

If you’ve ever tried bundling a native Node addon in an Electron app, you know the pain: platform‑specific builds, node‑gyp nightmares, ARM vs x64 headaches.

sql.js sidesteps all of that. The database runs entirely in WASM inside the renderer process. The trade‑off: you manage persistence yourself (serialize to disk on save). For a single‑user desktop app with small datasets, it’s a perfect fit.

// Persisting the DB is just:
const data = db.export();
fs.writeFileSync(dbPath, Buffer.from(data));

Simple. Clean. No native deps.

What’s next

  • Invoicing tool integration – connect KronoBar directly to your billing workflow
  • External app sync – an open interface to push your data to third‑party tools (Notion, Airtable, you name it)
  • Weekly reports – get a proper summary of your week, ready to share or archive
  • Windows – maybe a conversion for Windows

Try it / Contribute

The project is open source under MIT. If you’re a freelancer or consultant dealing with multi‑client time tracking, give it a spin – and feel free to open an issue if something doesn’t work or if you have ideas.

👉 github.com/splyy/KronoBar

git clone https://github.com/splyy/KronoBar.git
cd KronoBar
chmod +x install.sh
./install.sh

⚠️ macOS may block the app on first launch since it’s not signed with an Apple Developer certificate. The install script handles this automatically with xattr.

Built with ☕ and mild frustration at existing time trackers.

Tags: #electron #react #typescript #macos #opensource #freelance #sqlite #sideproject

0 views
Back to Blog

Related posts

Read more »