Moth is a git-style, file-based issue tracker that stores issues as markdown files. It's designed to be simple, transparent, and git-friendly, offering an alternative to commericial issue tracking systems.
Moth focuses on tracking the number of completed issues rather than story points. This approach is based on research indicating that story point estimates often have significant variance and may not accurately predict delivery timelines. We recommend using issue count as a more reliable metric for measuring team capacity and velocity.
- File-based storage: Issues are markdown files stored in
.moth/{status}/ - Git-friendly: Everything is plain text, perfect for version control
- Simple workflow: Move issues through customizable statuses
- Priority support: Track issue priority (crit, high, med, low)
- Priority ordering: Order stories within prioritized columns (e.g., backlog)
- Git commit hook: Automatically tag commits with active story ID
- Partial ID matching: Use short IDs to reference issues
- Reporting: Extract story change history from git commits as CSV
- Configurable: Customize statuses, priorities, and editor
brew tap tsmarsh/moth
brew install moth# Add the repository
echo "deb [trusted=yes] https://tsmarsh.github.io/apt-moth stable main" | sudo tee /etc/apt/sources.list.d/moth.list
# Update and install
sudo apt update
sudo apt install mothSupported architectures: amd64, arm64
cargo build --releaseThe binary will be available at target/release/moth.
# Initialize moth in your project
moth init
# Create a new issue
moth new "Fix login bug" -s high
# Create and immediately start working on an issue
moth new "Urgent fix" -s crit --start
# List issues
moth ls
# Move issue to "doing" (sets as current story)
moth start x7k2m
# Mark issue as done (clears current story)
moth done x7k2m
# Mark current issue as done (no ID needed)
moth done
# Show issue details
moth show x7k2m
# Show current issue details (no ID needed)
moth show
# Edit issue content
moth edit x7k2m
# Update issue description from stdin (replaces entire content)
echo "Updated specification" | moth update x7k2m
echo "New description" | moth update # updates current issue
# Delete issue
moth rm x7k2m
# Install git commit hook
moth hook install
# Set priority order (for prioritized columns)
moth priority x7k2m top
moth priority x7k2m 5
moth priority x7k2m above abc12
# Compact priority numbering
moth compact ready
# Generate CSV report of story changes
moth report --since HEAD~10| Command | Description |
|---|---|
moth init |
Create .moth/ structure with default config |
moth new "<title>" [-s severity] [--start] [--stdin] |
Create issue in first status (optionally start immediately) |
moth ls [-t status] [-s severity] [-a] |
List issues (default: all except last status) |
moth show [id] |
Display issue content (current issue if no ID) |
moth start <id> |
Move issue to statuses[1] and set as current |
moth done [id] |
Move issue to statuses[-1] (current issue if no ID) |
moth mv <id> <status> |
Move issue to any status |
moth edit <id> |
Open issue in editor |
moth update [id] |
Replace issue description with stdin content (current issue if no ID) |
moth rm <id> |
Delete an issue |
| Command | Description |
|---|---|
moth priority <id> top |
Move story to top of prioritized column |
moth priority <id> bottom |
Remove priority ordering (moves to bottom) |
moth priority <id> <number> |
Set specific priority number |
moth priority <id> above <other-id> |
Place story above another |
moth priority <id> below <other-id> |
Place story below another |
moth compact [status] |
Renumber priorities sequentially (1,2,3...) |
| Command | Description |
|---|---|
moth hook install [--force] [--append] |
Install prepare-commit-msg hook |
moth hook uninstall |
Remove moth git hook |
moth report [--since] [--until] |
Generate CSV report of story changes |
The configuration file is located at .moth/config.yml:
# Workflow statuses (first = default for new issues, last = "done" equivalent)
statuses:
- name: ready
dir: ready
prioritized: true # Enable priority ordering for this column
- name: doing
dir: doing
- name: done
dir: done
# Default severity for new issues
default_severity: med
# Editor for `moth edit` (falls back to $EDITOR, then vi)
editor: nvim
# ID generation length (3-10)
id_length: 5
# Skip editor when creating issues (useful for quick issue creation)
no_edit: false
# Priority ordering settings
priority:
auto_compact: false # Auto-renumber on every priority changestatuses[0]: Wheremoth newcreates issuesstatuses[1]: Target formoth startstatuses[-1]: Target formoth done- At least 2 statuses required
default_severitymust be one of:crit,high,med,low
.moth/
├── config.yml
├── .current # Tracks active story ID for git hooks
├── ready/ # Prioritized column
│ ├── 001-x7k2m-high-fix_login_bug.md
│ ├── 002-p3j9n-med-add_dark_mode.md
│ └── q8w3r-low-update_readme.md
├── doing/
│ └── a9f4k-crit-security_patch.md
└── done/
└── b2h8l-low-update_docs.md
Note: Moth automatically recreates missing status directories (e.g., if git removes empty directories). As long as config.yml exists, moth will recover gracefully.
- Format:
[order-]id-priority-slug.md - Order (optional): 3-digit priority number for ordering within prioritized columns
- ID: Random lowercase alphanumeric (default 5 chars), e.g.,
a3f8k - Priority: One of
crit,high,med,low - Slug: Snake_case derived from title
- Examples:
- Unprioritized:
x7k2m-high-fix_login_bug.md - Prioritized:
001-x7k2m-high-fix_login_bug.md
- Unprioritized:
Priority ordering allows you to control the order stories should be worked within specific columns (like a backlog). Enable it per-column in your config:
statuses:
- name: ready
dir: ready
prioritized: true # Enable ordering for this column- Stories in prioritized columns can have an order number (001, 002, etc.)
- Stories with order numbers appear first, sorted numerically
- Stories without order numbers appear last, sorted by priority/slug
- Moving stories out of prioritized columns automatically strips the order number
# Move story to top priority
moth priority abc12 top
# Set specific position
moth priority abc12 5
# Position relative to another story
moth priority abc12 above xyz89
moth priority abc12 below xyz89
# Remove priority (moves to bottom)
moth priority abc12 bottom
# Clean up gaps: 1,5,12 → 1,2,3
moth compact readyMoth can automatically tag your commits with the active story ID, making it easy to track which commits belong to which story.
# Install the git hook
moth hook install
# Start a story (sets it as current)
moth start abc12
# Make commits - they'll be automatically tagged
git commit -m "Fix the bug"
# Becomes: "[abc12] Fix the bug"
# Complete the story (clears current)
moth done abc12moth start <id>writes the story ID to.moth/.current- The
prepare-commit-msghook reads.currentand prepends[id]to commit messages moth done <id>removes.current- Commits made without an active story are unmodified
- Skips merge and squash commits
- Won't double-tag messages that already have a
[tag]prefix - Works from any subdirectory in your repo
- Use
--appendflag to add to existing hooks
Extract story change history from git commits as CSV:
# Generate report for recent commits
moth report --since HEAD~50
# Report for specific time range
moth report --since "2024-01-01" --until "2024-12-31"
# Full history
moth reportThe report includes: timestamp, story ID, event type (created/moved/edited/deleted), and details.
Moth supports execution of a custom script before and after each command.
Hooks are placed in the .moth/hooks/ directory and named according to the command they are associated with. E.g. it follows the structure: /[before|after]/<script name>:
./moth/hooks/
new/
before/
after/
setup-git-branch.sh
done/
before/
after/
commit-final-spec-changes.sh
Run the full test suite:
# Run all tests (integration + e2e)
cargo test
# Run only integration tests
cargo test --test integration_test
# Run only e2e shell tests
cargo test --test e2e_shell_testThe project includes:
- 27 integration tests: Direct function testing
- 19 e2e shell tests: Full CLI workflow testing via shell commands
- 43 cucumber scenarios: BDD feature tests
This project is open source.
