A project tracker with a chat thread attached to every task, so the discussion and the record live in one place instead of two.
Build me an issue tracker with discussion attached, replacing Height — and know why this is ALMOST. The tracker is ordinary work. The idea worth copying is **a chat thread on every task**, so the discussion and the record are one thing rather than two. That needs real-time delivery, correct unread state and notifications people trust, which is where the effort goes — and if the chat is not good enough that people actually use it instead of a separate messaging app, the whole premise collapses. STACK - Node 20+ with Fastify, server-rendered HTML with vanilla JS for the live parts - SQLite through better-sqlite3, WAL mode, with FTS5 - WebSockets for delivery, with a polling fallback - Caddy in front THE DATA MODEL - lists: id, name, key, description, is_archived — projects, in whatever you call them - tasks: id, list_id, number, title, description_md, status_id, assignee_id, due_at, estimate_minutes, priority, position, parent_id, completed_at, created_at - statuses: id, scope, name, group, position — the group is one of not-started, active, done, cancelled, and every report depends on it. Custom names, fixed groups - messages: id, task_id, author_id, body_md, body_html, created_at, edited_at, client_key — the thread - activity: id, task_id, field, old, new, actor_id, at — append-only - reads: user_id, task_id, last_read_message_id, last_read_at — the table that makes the whole thing usable - subscriptions: who follows what, derived from commenting, assignment and explicit follows - attachments, reactions, mentions, dependencies, custom fields THE THREAD, WHICH IS THE PRODUCT - Messages and activity interleaved in one timeline, so 'the status changed and here is why' reads as one conversation. That interleaving is the actual insight - A message is written to the database first, then broadcast. Never the other way round - Every message carries a client key so a resend after a dropped connection deduplicates rather than doubling - On reconnect, ask for everything since the last known message id and receive it in order. That endpoint is what makes it feel reliable - Unread per task, correct, with a clear list of what has new activity. A tracker that marks everything unread is one people stop opening - Mentions notify immediately; everything else batches into a digest. An over-notifying tracker is filtered into a folder nobody reads - Presence is unnecessary here. A task thread is asynchronous by nature and cursors would be noise VIEWS - List, board, calendar, and a spreadsheet-like table, all from one query builder with four renderers - Filters saved as views, shareable by URL, permissions checked inside the query - Ordering by fractional positions, not floats, or tasks will swap places after enough drags THE REST - Task numbers per list, allocated in the creating transaction and never reused. That name goes into commit messages and stays there forever - Sub-tasks one level deep, and relations — blocks, blocked by, relates to, duplicates — recorded once and shown from both sides - Search with FTS5 across titles, descriptions and messages, which is where the value of keeping discussion here really shows: a decision made in a thread is findable two years later - Git integration: a branch or commit mentioning the task key links to it, through a webhook with signature verification. Read the events, never write to the repository - Export everything as JSON including messages, in one command OPERATIONS - .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, SESSION_SECRET, OIDC_*, SMTP_URL, FORGE_WEBHOOK_SECRET - Migrations on boot, each once; the WebSocket layer in its own process - Nightly backup off the machine, restore script - Health endpoint WHAT MATTERS MOST Read state and reliable delivery. If people cannot trust that they have seen everything on a task, they will keep the conversation in a messaging app and the tracker becomes a form again.
What you lose
- A chat thread per task that people actually use, which needs real-time delivery and notifications
- Views over the same tasks — list, board, calendar, spreadsheet
- Search across tasks and their conversations together
If you would rather not build
- GitHub Issues, where the thread already works this way
What it costs
as published on their pricing page
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $9.99/mo | — | — |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
Vikunja
$0A lighter self-hosted tracker with several views over one list.
go-vikunja/vikunjafree · open source
Why this verdict
our own opinion · changed only by a person
58/100
Verdict kinda at 58. Merging field changes and comments into one timeline is the good idea and is easy; live delivery and restrained notifications are the weekend.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about Height
answered from the record above
Is Height free?
No — the plan we track is $9.99 a month. Around $9.99 per member per month billed monthly, cheaper annually.
Can you replace Height by building your own?
ALMOST. A weekend of work, and real gaps remain. Replacement score 58 out of 100, build time a weekend. Read what you lose before you decide.
How much does Height cost?
$9.99 a month on Team — $119.88 a year. Recorded 10 Aug 2026.
What do you lose by replacing Height?
A chat thread per task that people actually use, which needs real-time delivery and notifications; Views over the same tasks — list, board, calendar, spreadsheet; Search across tasks and their conversations together. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Height?
Yes: Plane, Vikunja. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

