Available now · Senior / Staff / Lead IC · Remote, US Available · Remote IC
Selected work

Grimoire · Solo design + build · 2026

An AI-native deck builder for Magic: The Gathering. Shipped to production solo in 15 days.

A collection manager and deck coach that stands on parity with Moxfield and Archidekt, and wins on one wedge: an AI coach that builds a legal Commander deck from the cards you already own. Live at grimoirestudy.com.

RoleSolo design + build + go-to-market
Timeline15 days · 406 commits
PlatformResponsive web · grimoirestudy.com
StackNext.js · Neon Postgres · Claude · Scryfall
StatusLive in production · early beta · creator push underway
Grimoire's deck editor in grid view: a 99-card Commander list grouped by type as full card images on the warm parchment builder surface — planeswalkers and creatures with quantity badges and prices — beside a full-size preview of Liliana, Death's Majesty. The sticky footer tracks 99 main cards, $653.53 to buy, 0% owned, a '1 illegal' warning, and a Bracket 4 badge.
The deck editor. Live prices, owned-vs-needed tracking, and format legality checked on every change — the "1 illegal" flag in the footer is doing real work.
The short version
ProblemThe dominant deck builders are deck-first: brilliant if you arrive with a list, silent about the cards you already own. Turning a real collection into a legal 100-card Commander deck is still hours of manual cross-referencing.
ApproachMatch the incumbents on table stakes — decks, collection, pricing, playtest — and put the entire innovation budget on one wedge: an agentic AI Deck Coach that interviews you, grounds every pick in real card data, checks legality, and saves a complete deck built preferentially from cards you own.
ResultLive at grimoirestudy.com. 66,761 lines of TypeScript across 52 routes and 179 components, in 15 days and 406 commits. Early beta: a handful of real users, a referral program in code, promoter outreach underway.
Honest lineThe build proved the velocity. The beta will prove the wedge. Distribution — not the product — is the open bet.

The system

A coach with tools, not a chat window

The Deck Coach is not a prompt wrapped in a textarea. It's an agentic tool loop: the model interviews you about intent, then works through up to sixteen tool steps — searching real card data, checking format legality, reading your collection, pulling commander statistics from EDHREC, finding combo lines, searching the web for recent meta shifts — before a single card is committed. The save itself is a tool call: idempotent, legality-checked, and owned-aware.

Intent interview → tool loop (searchCards · checkLegality · lookupCollection · commanderResearch · findCombos · web search) → saveDeck (legal, idempotent, owned-aware) → readiness score + buy list

Grimoire's AI Assistant hub: a flagship Deck Coach card described as 'a conversational coach that builds a deck with you — leads with questions, infers intent, prefers the cards you already own, grounds every pick in real card data' with a Start Building button, above a grid of secondary tools including Rules Judge and Roast My Deck.
The assistant hub. One flagship (the Coach), smaller utilities behind it.
A public Grimoire deck page for 'Lathril, Blade of the Elves': Commander badge, bracket indicator, total value of $1,790.96, like and bookmark actions, a Build Your Own call to action, and the full list grouped by card type with color pips and per-card prices.
What a shared link opens: a full read-only deck, no account needed.

The detail that defines the product

When the Coach saves a deck, it doesn't save a generic card reference. resolveOwnedPrinting resolves each card to the most valuable printing you actually own — your foil, your special-art version — and falls back to a standard printing only for cards you still need. Every other builder saves an abstract list; Grimoire saves your deck, then hands you the buy list for the gap.

Cost is a design constraint

An AI feature that loses money per use isn't a feature, it's a countdown. The Coach runs on Sonnet (roughly $0.30–0.50 per full deck build); Opus is reserved for the heavy analysis surfaces where depth is the point. Credits are enforced atomically — a conditional UPDATE … WHERE balance ≥ cost, no check-then-spend race — under a hard cap of about $3 per user per month, and a build is only charged when it completes. A failed generation is free.

The hard part: a local copy of every card ever printed

Resolving imports against Scryfall's live API got rate-limited and silently dropped cards. The obvious fix — parse Scryfall's bulk data file — crashes Node outright: the JSON is ~530 MB, past V8's maximum string length. The fix that shipped streams the download to disk, then stream-parses the array one object at a time with a hand-written brace-depth scanner (memory stays flat regardless of file size) and batch-upserts 500 rows at a time, idempotently. A 2,700-card collection import went from per-card API resolution — where rate limits silently dropped cards — plus ~13,500 row-by-row database writes that stalled around row 900, to a handful of batched local queries. Imports now resolve entirely against Grimoire's own catalogue.

Transferable: the pattern — constrain the model with real-data tools and make the save a validated, idempotent operation — applies anywhere "plausible" isn't "correct": config generation, compliance tooling, catalog and pricing surfaces, agent builders.

The problem

Deck-first tools ignore the shoebox

Commander is Magic's most popular format: 100 unique cards, color-identity rules, a power-bracket system, and a secondary market where a single list can price out at four figures. The established tools serve players who already know what they're building. Nobody starts from the other end — the pile of cards you actually own.

Competitive gap

ToolStrengthWhy it falls short
MoxfieldThe default deck database; deep format supportDeck-first. Collection is an afterthought; nothing builds for you
ArchidektVisual builder, rich categorizationSame deck-first assumption; steep for newer brewers
EDHRECMeta statistics for every commanderRecommendations, not a finished legal deck; blind to your cards
TCGplayer / Card KingdomPricing and purchaseNo bridge from "what I own" to "what this deck needs"

The scope call that made 15 days possible: match Moxfield's depth where it's table stakes; don't try to out-build it. Deck CRUD, collection tracking, pricing, sharing, and a playtest engine are parity features, built to be credible rather than superior. The innovation budget went entirely to the one job nobody does: collection → coached deck → buy list.

A live four-player Grimoire pod on the dark playtest board: seats for Alice, Carol, Bob, and Dave, each at 40 life with commander-damage trackers, a turn banner reading Carol's turn, Turn 1, a phase strip from Untap through End, the host's hand of seven real cards along the bottom, and battlefield lanes awaiting the first plays.
The "parity" feature that isn't: a real four-player Commander pod. The whole game is one serializable state object in a single Postgres row — no game server, no sockets — with each seat's hidden hand redacted server-side.
Grimoire's deck editor on a phone: a full-width add-cards search with an import button, a Non-foil/Foil/Etched finish selector, board tabs for Main, Sideboard, and Considering, a Display options button beside a grid/list toggle, a type-grouped card list with quantity steppers and prices, and a sticky footer showing 99 main cards, 99 to buy, $653.53, a 1-illegal flag, and a Bracket 4 badge.
The same editor on a phone — Magic players brew at the kitchen table, not the desk.
Grimoire's landing page on a phone: 'Your cards, your decks, in one Grimoire' over commander art, a description of the AI-native collection manager, Create Your Account and Sign In buttons, and a 'browse community decks — no account needed' link.
Zero clicks to value: featured community decks render before any signup.

Four decisions that drove the design

The non-negotiables

Collection-first, not value-first

The tempting home screen is "your collection is worth $3,936" — a number that flatters and goes nowhere. I rejected the portfolio-tracker framing; value is a secondary lens. The home surface leads with what your cards can do: decks you can build, decks that are close, what's missing.

Your most valuable printing, not a generic one

The alternative every competitor ships — resolve saved cards to a default or cheapest printing — is simpler and wrong. The deck you sleeve is made of the cards you own. resolveOwnedPrinting was more work at save-time and it's the difference between a list and your list.

Sonnet by default, Opus where it earns it

Everything-on-Opus tested better on nuance and would have made every free build a loss. The Coach runs on Sonnet; Opus is reserved for deck analysis and collection insights, where users read the output slowly. Unit economics were designed with the feature, not retrofitted after launch.

Card images bypass the image optimizer — deliberately

Card art is the most-rendered asset in the product, and routing it through a metered optimization service means one viral day makes every card in production go blank when the quota exhausts. Images ship unoptimized, straight from Scryfall's CDN. Less elegant on paper; strictly fewer ways to fail.

One consequence worth stating plainly: the fastest path to value needs no account — the landing page renders featured decks at zero clicks, and a full read-only deck is one click away — but deck building itself is auth-gated. That's a deliberate trade: every Coach run costs real money, so the free tier is metered per-account rather than open to anonymous traffic.

Failure modes

What happens when the model — or the upstream — is wrong

A product built on someone else's card database and a probabilistic model needs explicit answers for the days both misbehave:

FailureWhat the system doesWhy
Scryfall down or rate-limitingExponential backoff honoring Retry-After, per-chunk failure isolation, local-catalogue fallbackA 2,700-card import shouldn't die because request 1,900 hit a 429
Coach saves a 99-card "Commander deck"Legality engine names the exact issue; the Coach self-corrects to exactly 100One-card-short was the most common model failure in testing
Card image fails to loadCascade: primary URI → Scryfall by-ID redirect → text box with the card nameA deck page never renders blank
Search finds nothingExplicit empty state with the query echoed and a loosen-the-filters nudgeDead ends need exits, not blank grids
Generation fails mid-buildCredits are charged only on successful completionA failed build is free; atomic gating means no double-spend race either
Grimoire's deck analysis and legality panel: a Quick Read scorecard rating the deck Strong 7.8 Bracket 4 with consistency, resilience, interaction, and speed meters, a plain-language weak-spot note about protection and recursion with an 'Ask the coach how to fix it' link, and a What To Fix section explaining the deck has 99 cards while Commander requires exactly 100.
The legality panel names the exact rule and the fix — and hands the problem back to the Coach.

What's deliberately imperfect: if the credit-metering table itself errors, the gate fails open and generation proceeds unmetered. A billing bug must never lock users out of the product; the cost of that stance is that a database hiccup means free AI until it heals. I'd make the same call again — and it belongs in the documentation, not hidden in a catch block.

What's not handled yet, stated plainly: connection loss mid-edit (ordinary edits are plain server actions — no offline queue, no optimistic draft; only the multiplayer playtest reconnects gracefully) and rate limiting / bot protection, which don't exist anywhere in the app yet. Both are known, neither is invisible.

Distribution

The go-to-market is part of the build

A deck builder with no players is a database. Unlike my other projects, Grimoire shipped with its distribution mechanics in the codebase from week one:

  • A referral ladder, not a referral link. Double-sided credit rewards, with named milestones — Advocate at 3 referrals, Champion at 5, Legend at 10 — so sharing has a progression, not just a coupon.
  • Zero-touch creator onboarding. Comped Pro is an allowlist applied automatically at sign-in. Onboarding an influencer is adding one line to an environment variable — no admin panel, no manual grants, no waiting.
  • Every public deck is a landing page. Shared decks render read-only with no account, carry a "Build your own" call to action, and are enumerated in the sitemap for search.

I'm actively working with Magic promoters and content creators on launch content now — that's the live experiment, and it's why the honest line up top says distribution is the open bet.

The gap I'd close first: per-deck social preview images and embeds don't exist yet, so a shared deck link renders a generic card in Discord and Twitter — and Discord is where Commander players live. For a share-driven growth loop, that's the highest-leverage missing piece, and it's at the top of the roadmap.

Reflection

What worked, what I'd do differently, when this approach is wrong

What worked

  • Parity-not-outbuild scoping. Deciding on day one which features only had to be credible freed the two weeks to be spent where the product is actually different. This is the same altitude call I make in team settings; the solo build just makes it visible.
  • AI-assisted velocity, human architecture. 66,761 lines in 15 days is Claude Code doing the typing. The calls that made the product work — the streaming ingest parser, the atomic credit gate, owned-printing resolution — came from debugging real failures, not from generation.
  • Cost design as product design. Model tiering, hard caps, and charge-on-success were designed with the AI features, not bolted on after the first invoice. Ascend taught me that lesson in the other direction.

What I'd do differently

  • Never ship a panel on stubbed data. The vendor-pricing providers (TCGplayer, Card Kingdom) are stubs, which means a "best place to sell" panel currently runs on fabricated numbers. It should have been feature-flagged off until the integrations were real. That's the first thing I'd fix, and it's the weakest part of the product today.
  • Tests where the money is. Twelve test files in a codebase this size is thin everywhere, but the credit-limit and deck-save paths — the revenue-critical ones — are the inexcusable gaps.
  • Reconcile estimates against reality. The internal AI-cost dashboard is an estimate that doesn't yet reconcile to the actual Anthropic bill. An estimate that's never checked is a guess with a UI.
  • Email before launch, not after. Transactional email is still a console-log stub, which blocks password resets and any lifecycle messaging. Fine for an invite beta; not fine one week after it.

When I wouldn't ship this approach

The 15-day parity-plus-wedge sprint works when the incumbents' feature set is well-understood, the underlying data is public commodity (Scryfall is a gift), and the wedge is genuinely orthogonal to what they do. It's the wrong play when correctness is the product: Grimoire's own Rules Judge shows the edge of it — without retrieval over the actual Comprehensive Rules it gives good answers, not judge-grade ones, and I say so in the roadmap rather than in the marketing.

Next on the roadmap: per-deck social previews, the deck-page redesign, retrieval-grounded rules answers, camera-based card scanning for collection intake — and the long game: Grimoire's own playtest win-rate data feeding the Coach, which is the moat none of the incumbents can copy from a card database.

Status

On Grimoire

Grimoire is portfolio work and a real product: live in production, customer-facing, with a paid tier and a creator program mid-launch. It exists to test a wedge hypothesis and to demonstrate what solo designer-developer velocity looks like with current tools — strategy, design, code, and go-to-market from one seat, in 15 days.

I maintain it on my own time and in small windows. I'm available for full-time senior, staff, or lead IC work. Grimoire does not compete with that.