Documentation

How it works

This page covers installation, the core model, every command, keyboard shortcuts, synchronization, and agent integration.

Installation

Epiq ships as a single binary (with an npm package alternative). The binary installs to ~/.local/bin by default.

Quick install (binary)

curl -fsSL https://raw.githubusercontent.com/ljtn/epiq/main/install.sh | sh

Override the location with EPIQ_INSTALL_DIR (or XDG_BIN_HOME), and pin a version with EPIQ_VERSION=v1.0.0.

Via npm

npm install --global epiq

Verify

epiq --version

Getting started in two steps

Epiq lives inside a Git repository — your issues can live where your code lives.

  1. Make sure you are inside a Git repository. For collaboration, use a repo with a remote (e.g. cloned from GitHub).
    # if needed
    git init
  2. Run epiq:
    epiq

On first run this opens an interactive setup wizard that gets you going in about 30 seconds. Once your project is set up, you can also launch the browser GUI:

epiq gui
What gets created. The setup wizard writes user config to ~/.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

The hierarchy

State is a tree of nodes. From the top down: workspaceboardswimlaneissue. Issues hold a description, tags, assignees, comments, and a full history log. Commands are context-aware — for instance :close only exists for issues.

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 description of the selected issue in your preferred external editor (no inline text — also bound to 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
: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
: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> Update editor, username, view, auto-sync, sync debounce, or log level
: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 ☕

Filtering

Apply a filter with :filter followed by a target and a value. To show every issue carrying an urgent tag:

:filter tag urgent

Run several :filter commands in succession to build a combination. Targets are tag, assignee, description, and title. Clear everything with:

:filter clear

Closing & reopening

Close an issue with :close. This moves it to a special board named Closed, which you can reach by navigating up (press q) a few times.

To bring it back, open the Closed board, select the issue, and run :reopen. The issue is restored to its previous location, resolved from its history log.

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

While peeking, the board is read-only; only viewing, exporting, and configuration are available.

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

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.

Tip. Frequent synchronization reduces divergence and keeps the system predictable. Enable :config autoSync on to sync automatically.

MCP & agents

Epiq ships an MCP (Model Context Protocol) server via the epiq-mcp binary, so AI agents can interact with your local instance.

Claude Code

The reliable way to register the server is with claude mcp add — it writes the correct config for you:

# available everywhere (recommended)
claude mcp add --scope user epiq -- npx -y -p epiq epiq-mcp

# or only in the current project
claude mcp add epiq -- npx -y -p epiq epiq-mcp

Verify with claude mcp list (it should report epiq … ✔ Connected). MCP servers load at startup, so restart Claude Code after adding the server.

Other MCP clients

For hand-configured clients, add the following to the client's MCP config file:

{
  "mcpServers": {
    "epiq": {
      "command": "npx",
      "args": ["-y", "-p", "epiq", "epiq-mcp"]
    }
  }
}

Export

Run :export to write the current board layout to a markdown file — handy for sharing a snapshot, generating reports, or feeding context to other tools.

:export