A fast TUI deck and collection manager for Magic the Gathering using golang.
Find a file
2026-02-08 09:50:05 +01:00
cmd import 2026-02-06 21:33:45 +01:00
doc scaffold 2026-02-06 19:01:49 +01:00
internal fix deck and collection detail flip UX 2026-02-08 09:50:05 +01:00
scripts only when lock and mod changes 2026-02-06 21:57:31 +01:00
.envrc Init 2026-02-06 18:47:41 +01:00
.fast-commit.toml Init 2026-02-06 18:47:41 +01:00
.gitignore chore: add result to .gitignore 2026-02-06 21:58:01 +01:00
AGENTS.md AGENTS and README 2026-02-07 08:22:31 +01:00
ARCHITECTURE.md docs 2026-02-07 19:46:50 +01:00
CODE_STYLE.md docs 2026-02-07 19:46:50 +01:00
devenv.lock vendor hash check 2026-02-06 21:54:25 +01:00
devenv.nix only when lock and mod changes 2026-02-06 21:57:31 +01:00
devenv.yaml vendor hash check 2026-02-06 21:54:25 +01:00
flake.lock flake 2026-02-06 21:51:26 +01:00
flake.nix flake 2026-02-06 21:51:26 +01:00
go.mod cards (broken) 2026-02-06 19:48:16 +01:00
go.sum cards (broken) 2026-02-06 19:48:16 +01:00
LICENSE.txt Init 2026-02-06 18:47:41 +01:00
main.go scaffold 2026-02-06 19:01:49 +01:00
README.md Syntax mode 2026-02-07 09:16:53 +01:00

Taplands

Local-first CLI/TUI app for Magic: The Gathering card browsing, deck building, and collection management.

Taplands is built with:

  • Go + Cobra (CLI)
  • Bubble Tea + Bubbles + Lip Gloss (TUI)
  • SQLite (MTGJSON source DBs + user data DB)

Current Status

Implemented right now:

  • First-run initialization flow with confirmation + installer TUI
  • Concurrent MTGJSON DB download/extract
  • Main menu + full-screen alt-screen TUI
  • Cards view with side-by-side list/detail, search modes (standard/fuzzy/syntax), scrolling
  • Multi-select card workflow in Cards (space, quantity with h/l)
  • Add selected cards to collections/decks from Cards (a/d)
  • Quick add to last-used collection/deck (A/D)
  • Collections and Decks two-step flow:
    • enter on list
    • left pane card list + right pane card detail
  • CLI deck/collection create + import flow from text files

Install and Run

Run directly:

nix run .

Install into profile:

nix profile add .

From remote repo:

nix run github:<owner>/<repo>
nix profile add github:<owner>/<repo>

Go

go run .

First Run Initialization

On first taplands start, Taplands checks local card DBs and (if missing) asks for confirmation, then downloads and extracts:

  • https://mtgjson.com/api/v5/AllPrintings.sqlite.xz
  • https://mtgjson.com/api/v5/AllPricesToday.sqlite.xz

You can also run init explicitly:

taplands init

Data Paths

  • Linux: ~/.local/share/taplands
  • macOS: ~/Library/Application Support/taplands

Layout:

taplands/
  cards/
    AllPrintings.sqlite
    AllPricesToday.sqlite
    cache/
  user/
    user-data.sqlite
  state/
    init-state.json

CLI Commands

Top-level:

  • taplands init
  • taplands db update
  • taplands import ...
  • taplands export ...
  • taplands deck create <name>
  • taplands collection create <name>

Import to Deck/Collection

taplands import deck <id-or-name> -i file.txt
taplands import collection <id-or-name> -i file.txt

Non-interactive mode:

taplands import deck <id-or-name> -i file.txt --yes
taplands import collection <id-or-name> -i file.txt --yes

Import behavior:

  • If target deck/collection does not exist, Taplands asks to create it first.
  • Prints summary (x out of x cards found, not found list, planned import count).
  • Asks confirmation unless --yes is provided.
  • Uses strict matching when set/collector/foil details are present.
  • Falls back to best name match when details are omitted.

Import File Format

Format:

[qty][x] CardName [(set)] [cardnumber] [foil identifier]

Notes:

  • qty optional, defaults to 1
  • x optional (4x or 4 are both valid)
  • foil identifier is *F*
  • set is written like (BLB)

Examples:

Example Card
1 Example Card *F*
4x Example Card
4x Example Card (BLB)
4 Example Card 543 *F*
1x Example Card (set) 123 *F*
1 Example Card 123

Export

taplands export deck <deck-id-or-name> --format deck

TUI Key Highlights

Global/common:

  • q quit
  • esc back
  • arrows + j/k navigate

Cards view:

  • / search
  • tab cycle search mode forward (fuzzy -> standard -> syntax)
  • shift+tab cycle search mode backward
  • space select/unselect card
  • h/l decrease/increase quantity for selected card
  • c clear selected cards
  • a add selected/current card(s) to collection
  • d add selected/current card(s) to deck
  • A quick add to last-used collection
  • D quick add to last-used deck

Taplands syntax mode is inspired by Scryfall's search language:

Supported right now (phase 1 subset):

  • Boolean logic: implicit AND, or, parentheses, negation with -
  • Exact names: !name and !"quoted name"
  • Keywords: c:/color:, id:/identity:, t:/type:, o:/oracle:, kw:/keyword:, m:/mana:, mv:/manavalue:
  • Stats: pow:/power:, tou:/toughness:, loy:/loyalty:, pt:/powtou:
  • Print metadata: r:/rarity:, s:/set:/e:/edition:, cn:/number:
  • Legality: f:/format:, banned:, restricted:
  • Extras: a:/artist:, ft:/flavor:, wm:/watermark:, produces:
  • Flags: is: and not: for common flags like reprint, reserved, funny, promo, full, foil, nonfoil, digital, commander, hybrid, phyrexian

Not supported yet:

  • Regex search syntax (/.../)
  • Price filters (usd:, eur:, tix: and numeric price comparisons)
  • Cube/tagger/search-display operators (cube:, art:, function:, display:, order:, unique:, prefer:)
  • Full Scryfall historical/reprint operators (new:, in:, prints=, sets= and related variants)
  • Date/year operators (date:, year:)
  • Full advanced mana semantics (devotion:, complete m> cost superset semantics)

Development

Devenv

Enter dev shell:

devenv shell

Useful scripts:

  • generate-jet -> regenerates Jet code from local SQLite DB files
  • check-flake-hash -> runs nix build .#taplands --no-link

Flake Vendor Hash Hook

Devenv git hook checks flake vendor hash only when staged files include:

  • flake.nix
  • flake.lock
  • go.mod
  • go.sum

This keeps commit-time checks fast while still guarding Nix package integrity when dependencies change.

Roadmap (Short)

  • Better import throughput and optional benchmark output
  • Deck/collection card edit/remove operations
  • Richer card detail rendering and prices/legalities polish
  • More export/import formats