A notes-taking and task-tracking app with a WYSIWYG markdown editor and kanban-style task board.
Design philosophy: Task management should never be separate from the thinking that produces it. Glyph treats your notes as the source of truth — write a bullet under a TODO heading and it becomes a trackable task automatically. No context switching, no copy-pasting into a separate tool. If you can write a bullet list, you can run a project.
- Rich editor — TipTap / ProseMirror. Typing
#becomes a heading,-becomes a bullet, etc. - TODO detection — Bullets under a
TODOheading automatically create linked tasks. - Kanban board — Configurable lanes with filters and sorting (auto, field, or manual).
- Page tree — Hierarchical pages and folders, unlimited depth.
- Search — Full-text search via
⌘Kmodal or dedicated search page (Fuse.js). - Two storage backends — LocalStorage (offline, no setup) or Go REST API + PostgreSQL.
| Layer | Choice |
|---|---|
| Frontend | SvelteKit 2, Svelte 5 (runes), TypeScript |
| Editor | TipTap 3 (@tiptap/core, @tiptap/starter-kit) |
| Styling | Scoped <style> + CSS custom properties |
| Search | Fuse.js 7 |
| Backend | Go (Gin), PostgreSQL 16, OIDC auth |
| Package manager | pnpm |
- Node.js 20+
- pnpm 9+
- Docker (for Postgres backend)
- Go 1.22+ (for API backend)
pnpm install
pnpm dev # http://localhost:5173 (localStorage mode)Docker Compose is used for local development only. All services run with live reload by default.
# localStorage mode — Vite dev server on http://localhost:5173
docker compose up
# Full stack (API + Postgres) — Vite on http://localhost:5173, Go API rebuilt on save via Air
docker compose -f docker-compose.yml -f docker-compose.postgres.yml upIn full-stack mode, the app is also available at https://localhost (self-signed cert via Nginx). Migrations run automatically — the migrate service runs once before the API starts and then exits; no manual steps required.
| Backend | How to reset |
|---|---|
| localStorage | Clear browser storage (DevTools → Application → Local Storage → Clear all) |
| Postgres | docker compose … down -v then up again (drops the volume; migrations re-run on next start) |
Glyph also ships as a native desktop app for macOS and Linux (src-tauri/) — a thin window that connects to your self-hosted Glyph server, with automatic updates.
Download the .dmg from the latest release. The app isn't notarized by Apple (notarization requires a paid Apple Developer account), so the first launch of a browser-downloaded copy is blocked by Gatekeeper with:
"Glyph" is damaged and can't be opened. You should move it to the Trash.
This is not actual corruption — Gatekeeper shows this message for any unnotarized app that was downloaded through a browser. Clear the quarantine flag once, after installing to /Applications:
xattr -cr /Applications/Glyph.appThen open the app normally. This is a one-time step: updates applied from inside the app are downloaded directly and are never quarantined, so future versions install without hitting this warning again.
Download the .deb or .AppImage from the latest release.
# Debian/Ubuntu
sudo apt install ./Glyph_*.deb
# AppImage
chmod +x Glyph_*.AppImage
./Glyph_*.AppImageOn first launch, Glyph asks for the URL of your self-hosted server. It's remembered after that; change it any time from the app menu (Glyph → Change Server URL…).
pnpm dev # start dev server (localStorage mode) at http://localhost:5173
pnpm build # production build (also catches type errors)
pnpm check # svelte-check + tsc type checking
pnpm preview # preview production buildThe Makefile is the single entry point for running tests and linters — it mirrors all CI jobs exactly.
make ci # everything: lint + unit tests + both E2E projects
make test # unit tests + both E2E projects (no lint)
make test-unit # fast: frontend vitest + Go unit tests only
make test-frontend # type-check, build, vitest
make test-go # go vet, build, unit tests
make test-e2e-local # Playwright local-storage project (no backend needed)
make test-e2e-api # Playwright API project via isolated Docker stack
make lint # all linters (svelte-check + golangci-lint + go vet)Run make help for the full reference.
cd api && go test ./... -shortRuns unit tests (handler, model, store, memstore packages). Pass -short to skip the integration suite that requires Postgres.
The make test-e2e-api target (and make ci) uses an isolated Docker stack to avoid conflicting with a running dev environment:
docker compose -f docker-compose.test.yml up -d --build --wait
pnpm test:e2e:api
docker compose -f docker-compose.test.yml down -vThis starts an ephemeral Postgres (port 5433) and Go API (port 8083) in their own Docker project (glyph-test), then tears everything down after the run.
src/
lib/
components/ # Svelte components (editor, sidebar, tasks, search, shared)
editor/extensions/ # TipTap extensions (TaskLink, TodoDetection)
models/types.ts # All TypeScript interfaces
search/ # Search provider abstraction (Fuse.js)
sort/ # Sort provider abstraction (Auto, Field)
storage/ # Storage layer (Repository, LocalStorage, API client)
stores/ # Svelte 5 rune stores (pages, tasks, lanes, ui)
routes/ # SvelteKit routes (notes, tasks, search)
api/
cmd/api/main.go # Go API entry point
internal/ # Auth, handlers, models, stores
migrations/ # PostgreSQL schema migrations
e2e/ # Playwright E2E test specs
See api/README.md for API-specific documentation.