how it works.
Installation
Binary
Installs to ~/.local/bin. Change that with
EPIQ_INSTALL_DIR (or XDG_BIN_HOME), and
pin a version with EPIQ_VERSION=v1.0.0.
npm
Verify
Getting started
- Open a Git repository, or create one. To collaborate, it needs a remote.
- Run Epiq. The first run opens a setup wizard.
Then, if you like, open the browser app:
~/.epiq-global/config.json. Initialization
adds a project definition at ./.epiq/project.json,
authoritative Git state at
~/.epiq-global/worktrees/<id>, and updates your
.gitignore to ignore local-only
.epiq/log/.
Core concepts
Event-sourced state
Every change is stored as an append-only event in a user-scoped log, rather than mutating a shared file. The current state is materialized in memory by replaying a merge of all user logs in a deterministic order (time-sortable ULIDs plus a reference to the last known event). This makes concurrent edits converge to the same state and keeps Git merges trivial.
Local-first
All operations apply instantly on your machine. Synchronization
happens explicitly with :sync or automatically. When
histories diverge, merging the event logs and replaying them leads
to a consistent state.
Command reference
Type : to enter command-line mode, then a command. Commands accept a modifier (in violet) and a free-text argument. Autocompletion suggests valid modifiers as you type, and the set of available commands depends on what is selected.
Create & edit
| Command | Description |
|---|---|
:new
issue|swimlane|board
<name>
|
Create a new board, swimlane, or issue |
:edit
title
<text>
|
Rename the selected node inline |
:edit
description
|
Open the selected issue's description in your editor (also e) |
:edit
comment
<text>
|
Edit the currently selected comment inline (only your own comments) |
:comment
<text>
|
Add a comment to the selected issue |
:delete
|
Delete the currently selected node |
:move
|
Move a node — usually triggered with m, then navigate and confirm |
Issue workflow
| Command | Description |
|---|---|
:tag
<name>
|
Add or create a tag on the selected issue |
:untag
<name>
|
Remove a tag from the selected issue |
:assign
<name>
|
Assign a user to the selected issue |
:unassign
<name>
|
Remove an assignee from the selected issue |
:yank
ref|title|description|tags|assignees
|
Copy the selected item's ref, title, description, tags, or assignees (also y) |
:close
|
Move the selected issue to the Closed swimlane |
:reopen
|
Move a closed issue back to its previous swimlane |
View & history
| Command | Description |
|---|---|
:filter
tag|assignee|description|title|clear
<value>
|
Filter the board; combine filters by running several in succession |
:peek
<offset>|<date>|now|prev|next
|
View the board's state at another point in time. Offset is
<n>h, d, w,
mo, or y (e.g. 3d);
or an absolute YYYY-MM-DD date
|
:replay
<offset>|<date>
[duration]
|
Replay board history forward from a point in time as an
animation, with an optional playback duration (e.g.
30s)
|
:export
|
Export the current board layout to markdown |
System & sync
| Command | Description |
|---|---|
:sync
|
Pull, commit, and push Epiq state via Git |
:config
editor|username|view|autoSync|syncDebounceMs|logLevel
<value>
|
Change a setting; see Configuration |
:init
|
Initialize Epiq in the current Git repository |
:help
|
Open the help screen |
:exit
|
Exit the application |
:coffee
1|3|5|20|custom
|
Sponsor the development of Epiq ☕ |
Time travel
Because state is a full event log, you can inspect the board as it
was at any point in the past. Use :peek with a time
offset, or step through history:
# jump to an offset: h, d, w, mo, y (e.g. 3 days ago)
:peek 3d
# or jump to an absolute date
:peek 2026-01-15
# step backward / forward through history
:peek prev
:peek next
# return to the present
:peek now
Where :peek shows a frozen snapshot,
:replay plays history forward from that point as an
animation — watch the board evolve event by event. The optional
second argument sets the playback duration:
# replay the last month of activity
:replay 1mo
# same, spread over a 30 second animation
:replay 1mo 30s
While peeking or replaying, the board is read-only; viewing, yanking to the clipboard, exporting, and configuration remain available.
Export
Run :export to write the current board to a markdown
file.
:export
Configuration
Adjust settings with
:config <setting> <value>.
| Setting | Description |
|---|---|
editor |
Preferred external editor for descriptions |
username |
Your display name on events and assignments |
view wide|dense |
Board layout density |
autoSync on|off |
Enable or disable automatic synchronization |
syncDebounceMs
<ms>
|
Debounce window for auto-sync in milliseconds (e.g. 5000, 15000, 30000) |
logLevel
debug|info|error
|
Logging verbosity |
The board
epiq gui serves the same board in the browser. Add
tickets and lanes in place, and narrow a busy board with the
filter box — it matches on ref or title.
epiq gui
uses port 3710, with a fallback to a free one. Settings are
persisted in localStorage, so on a new port the
timeline selections etc. start fresh. Reclaim 3710 to get them
back.
Tickets & commits
Clicking a ticket opens its panel, docked to the right or along the bottom. Descriptions and comments take markdown, and images can be pasted or dropped straight in.
The Code tab lists every commit linked to the ticket, with its message, diffstat and per-file diff. Comment on any line, or mark a file as reviewed.
Timeline
Drag the scrubber across the history to check out the board as it was at that moment, as volume per period or as individual events. The header reads Read-only while you are in the past, and Now brings you back.
Sync & Git
Epiq uses Git in the background — no manual Git commands required.
Running :sync synchronizes changes between your local
state (at ~/.epiq-global/worktrees/<id>/) and
the remote. By using Git worktrees, synchronization stays isolated
from your regular development workflow.
Changes are append-only events in user-scoped files, so Git merges become trivial combinations of independent files. Later events take precedence when conflicts occur, and idempotent events keep concurrent updates predictable.
:config autoSync on.
MCP & agents
The epiq-mcp binary is an MCP server, so agents can
work your board.
Claude Code
Register it for every project:
Or for the current project only:
Restart Claude Code, then check with claude mcp list:
it should report epiq … ✔ Connected.
The Epiq skill
The server tells an agent what it can do; the
skill
tells it how to work the board. Ask the agent to run
epiq_skill_install, or fetch it yourself:
Epiq-Ref: line naming the ticket's
ref, the seven characters :yank ref copies:
git commit -m "fix the parser" -m "Epiq-Ref: A1B2C3D".
One line can name several refs, comma-separated. A subject that
starts with the ref links too:
git commit -m "A1B2C3D fix the parser". Linked commits
show in the ticket's Code tab. An Epiq-Ref line survives a squash
merge that keeps the squashed messages, as GitHub's default does;
a prefix needs the commits rebase-merged as they are.
Other MCP clients
Add this to the client's MCP config file:
{
"mcpServers": {
"epiq": {
"command": "npx",
"args": ["-y", "-p", "epiq", "epiq-mcp"]
}
}
}