(Nil) => {To.Dev;}

· Updated

Building .Ember (DotEmber)

All-in-one productivity Mac app


.Ember (DotEmber) is an all-in-one productivity app for macOS. Journal, todos, calendar, timer, news reader, and stats — every part of the day in one minimal interface.

The page below is about design decisions and why they were made.

Why I built it

Journal view
Journal view

Like many, I was using a separate app for each of journal, todos, calendar, timer, and RSS. That flow inevitably stacked a cost — five different environments, five different ways of doing things. I’d open three of them in the morning and, by the time I got to the fourth, couldn’t care less.

I didn’t need a more sophisticated single app. I needed one that fit my day. So I started building .Ember.

Design — as minimal as it gets

Todo + Calendar
Todo + Calendar

The visual language is inspired by the apps I already use daily: Obsidian’s vault model and simplicity, the calmness of native macOS. Tight spacing, two-tone purple accent, no decorative chrome. On narrow windows the sidebar collapses to icons so the macOS traffic-light cluster fits cleanly inside it. Every animation is 100–200 ms — fast enough to feel responsive.

One decision sits behind all of them: nothing on the screen unless it earns its pixels.

ADHD-friendly — with as little friction as possible

Focus Daily Entry
Focus Daily Entry

What I needed most wasn’t another feature — it was less friction at the moment of starting. So there’s a Focus Daily Entry mode. The first time you open the app on a given day it gives you a full-screen Journal + Todo capture wizard. No sidebar, no tabs, no decision about which view to be in — write, then list what you want to do today.

The smaller things matter just as much. Blocks let you bucket todos by context (Routine, Work, Personal, whatever you make) and run a block straight into the timer. The command palette (Cmd+K) is one keystroke from anywhere. Repeat-rule todos seed themselves automatically each morning, but they don’t inflate the “I didn’t do anything today” feeling because the system tells the difference between an auto-renewed habit and a thing you typed in.

Local-first — your data is always yours

Sync settings
Sync settings

Like many Obsidian users, I’m more comfortable when the data is mine to hold directly. .Ember stores everything as plain Markdown in a folder you choose — point it at an iCloud Drive folder, a Documents subfolder, a USB stick. The Markdown is the source of truth; the SQLite database next to it is a search-index cache that the app can rebuild any time.

iCloud sync is optional, going through Apple’s CloudKit private DB so your data stays in your own iCloud account. There is no NilToDev server. RSS feeds fetch directly from publishers. AI features use your own API key and are off by default.

A note for Obsidian users. There’s an optional Obsidian Sync feature, but it expects two distinct folders — one for the .Ember vault, one for Obsidian, never the same path. The sync engine mirrors Markdown between them on a schedule you set, with a dry-run preview on the first run and conflict-loser files preserved automatically. Pointing the app at a folder that already contains an .obsidian/ workspace is not supported. See “Can I use .Ember with Obsidian?” in the Q&A.

Stack

This is my first Mac app, so I picked the stack I could move fastest on:

  • Electron + electron-vite — cross-platform-ready (a mobile companion is on the post-1.0 roadmap) with a build pipeline that’s a single pnpm dev away.
  • React 19 + TypeScript — honestly, the ecosystem with the most documentation and community to lean on.
  • Tailwind 4 + custom CSS variables — every color is a var(--accent-*), so a single accent-picker change re-themes 100+ components in one paint.
  • Zustand — one store per feature, no boilerplate, no provider tree.
  • Tiptap (ProseMirror) — Markdown editor surface, with a custom toolbox on top.
  • better-sqlite3 — synchronous, native, fast enough that FTS5 search returns instantly.
  • Apple CloudKit JS — sync without writing a backend.

If I were to build this app again, I’d probably try SwiftUI.