MD Sticky Notes is a native macOS task and note app for people who need their work to stay visible. It combines floating Markdown notes with optional Google Tasks synchronization.
Instead of making every task live in one passive checklist, MD Sticky Notes turns tasks into floating Markdown windows that can stay on screen, carry due dates, use colors, and optionally sync with Google Tasks.
Normal task apps are easy to ignore when the task list is out of sight. MD Sticky Notes is built around visual persistence:
- tasks can stay as always-available floating notes
- markdown keeps notes flexible enough for checklists, context, links, and quick dumps
- due dates and Google Tasks sync keep the same utility as a conventional to-do app
- colors and separate windows make different kinds of work easier to scan at a glance
- Floating markdown sticky notes with live preview
- One shared
WKWebViewreparented across note windows to keep memory usage low - Local SQLite persistence for note content, window state, sync state, and mutation outbox
- Optional Google Tasks sync through the repo-local
backend/service - Global modifier chords that work while another app is focused: release Control+Option to create a note and release Option+Command to show/hide notes
- Per-note due dates, custom colors, and manual
Sync Now
This public repo does not include live credentials. Real secrets should stay in local environment files, GitHub repository secrets, macOS Keychain, Google Secret Manager, or another secret store.
Ignored or intentionally absent from the public source:
backend/.envandbackend/.env.local- OAuth client JSON files
- Apple signing certificates and provisioning files
- GitHub, Google, database, and app-session tokens
- local databases, build outputs, app bundles, and
node_modules - agent-only local instruction files
The backend stores Google refresh tokens encrypted at rest, and the macOS app stores backend session tokens in Keychain.
- macOS 12+
- Swift 5.9+
- Node.js 18+
- Local Postgres if you want to exercise the backend
./build-app.sh
open build/StickyNotes.app./scripts/dev-run-backend.shIn another terminal:
./scripts/dev-build-app.sh
open build/StickyNotes.appInside the app:
- Open
Settings - Enable
Use Custom Backend URL (Development) - Leave the custom URL as
http://127.0.0.1:8787 - Click
Sign In With Google
In mock mode that sign-in completes locally and exposes fake task lists so you can test note creation, list selection, due dates, deletes, and Sync Now.
The macOS app talks to the backend, and the backend owns the Google OAuth refresh token.
- Create a Google OAuth web application client
- Enable the Google Tasks API
- Set the redirect URI to the backend callback URL
- Fill out
backend/.envfrombackend/.env.example
Then:
cd backend
npm install
npx prisma migrate deploy
npm run devIn the app, enable the custom backend override, point it at http://127.0.0.1:8787, sign in, choose task lists, and use Sync Now.
More details are in backend/README.md.
This repo includes the repo-side pieces needed to run a hosted private beta:
- multi-user backend lookup keyed by Google subject instead of a single local user
- an authenticated optional cron endpoint at
POST /internal/cron/sync - a Railway service rooted at
backend/with managed Postgres and/healthzreadiness checks - a backend Dockerfile and additive Prisma migrations
- build pipeline support for Developer ID signing, hardened runtime, notarization, stapling, ZIP, and DMG artifacts
Key production files:
The canonical production API is https://backend-production-15d8.up.railway.app. Localhost is supported only through the explicit development override in Settings. The files under infra/gcp/ and the GCP scripts are optional reference material and are not invoked by CI.
Local builds work with ad-hoc signing by default:
./build-app.shSigned and notarized release builds require Apple credentials:
export APPLE_DEVELOPER_IDENTITY="Developer ID Application: Your Name (TEAMID)"
export APPLE_NOTARY_PROFILE="your-notarytool-profile"
export ALLOW_ADHOC_SIGNING=0
./build-app.shUseful environment overrides:
APP_VERSIONAPP_BUILDPRODUCT_BUNDLE_IDENTIFIERAPP_DISPLAY_NAMESKIP_DMG=1SKIP_ZIP=1CREATE_STYLED_DMG=1
Sources/StickyNotes: Swift/AppKit shell, native windows, persistence, sync clienteditor-web/src/editor.js: CodeMirror 6 editor and markdown rendering logicbackend/src: Fastify + Prisma backend for OAuth, sync state, projection, polling, and SSE
The most important app-level architectural choice is that it uses one shared WKWebView across note windows. The active window owns the live editor and inactive windows show snapshots or previews.
The complete component, function, route, sync-flow, and hosting map is in docs/architecture.md.
MIT
