๐ฎ Scryglass
Scry, shuffle, and goldfish your Magic: The Gathering decks โ offline, at the table, no account required.
Scryglass is a free, open-source Progressive Web App (PWA) that replaces physical deck manipulation for MTG goldfishing and casual play. It runs entirely in your browser, works offline after first load, and is designed for use on a phone lying flat on a game store table.
No installation. No account. Just open and play.
- Visit the app at
scryglass.cards - Paste your deck list (Scryglass CSV format, or import from Moxfield/Archidekt/MTGO)
- All players load their decks โ automatic shuffle โ opening hands dealt
- Play! Draw, scry, tutor, and fetch โ Scryglass handles the library for you
- ๐ Cryptographically fair shuffle โ Fisher-Yates algorithm with
crypto.getRandomValues()and rejection sampling (ADR-004) - ๐ฑ Offline-first PWA โ Install to your home screen, play without WiFi after first load
- ๐ Full library manipulation โ Draw, scry, tutor, fetch basic lands, return to library
- ๐ Strict mulligan engine โ Auto-mull on 0/1/6/7 lands, hard keep on 3/4, optional choice on 2/5
- ๐ผ๏ธ Card images via Scryfall โ Background prefetch with IndexedDB caching and JIT priority loading
- ๐ฅ Multi-format import โ Supports Moxfield, Archidekt, and MTGO/Arena deck formats
- ๐ค Multi-format export โ Export your deck to any supported format
- ๐ฅ Multiplayer support โ multiple-deck UI with player isolation (no peeking!)
Scryglass was born out of a simple frustration: shuffling takes too long. I originally built this so I could play Magic with my kids. Previously, I was spending half of our "playtime" physically manipulating our cards. I wanted a way to let the computer handle the mechanics of the library so we could focus on actually playing the game together.
Beyond saving time at the kitchen table, Scryglass is built to solve a few specific problems:
- Protecting High-Value Collectibles: Play with your physical dual lands, foils, and reserved list cards without subjecting them to the wear and tear of constant mash-shuffling.
- Accessibility: 100-card Commander decks are physically difficult to manipulate. Scryglass removes the physical barrier of dexterity required to shuffle, fetch, and handle a massive deck.
- Frictionless Goldfishing: Test your latest brews instantly. Just paste your Moxfield link and start drawing hands without needing to sleeve up a single card.
All significant decisions are documented as Architecture Decision Records:
| ADR | Title |
|---|---|
| ADR-001 | Use Architecture Decision Records (ADRs) to Document Decisions |
| ADR-002 | Preact + Vite for the PWA |
| ADR-003 | Scryfall API integration & compliance |
| ADR-004 | Fisher-Yates shuffle with Web Crypto API |
| ADR-005 | Action/Reducer state management โ agent-ready game engine |
| ADR-006 | Semicolon-delimited deck import format |
| ADR-007 | Monorepo structure (core/PWA separation) |
| ADR-008 | TypeScript & Zod for strict typing |
| ADR-009 | Client-side routing strategy |
| ADR-010 | Local storage strategy for decklists |
| ADR-011 | End-to-end testing strategy |
Scryglass is built as a monorepo with strict separation of concerns:
| Package | Purpose | Browser Dependencies |
|---|---|---|
@scryglass/core |
Pure game logic: deck parsing, cryptographic shuffle, state management, mulligan rules, library manipulation | โ None โ runs in Node.js and browsers |
@scryglass/pwa |
Preact + Vite frontend: UI rendering, Scryfall API integration, IndexedDB caching, Service Worker | โ Browser APIs required |
The @scryglass/core module uses a strict JSON-in/JSON-out action-reducer pattern with Zod schema validation, making it suitable for consumption by AI agents, CLI tools, or any TypeScript/JavaScript consumer.
scryglass/
โโโ packages/
โ โโโ core/ # @scryglass/core โ game logic library
โ โ โโโ src/
โ โ โโโ package.json
โ โ โโโ tsconfig.json
โ โโโ pwa/ # @scryglass/pwa โ Preact + Vite frontend
โ โโโ src/
โ โโโ package.json
โ โโโ tsconfig.json
โโโ meta/ # Development philosophy, ADRs, and plans
โ โโโ adr/ # Architecture Decision Records
โ โโโ plans/ # Implementation plans and roadmaps
โโโ docs-src/ # Documentation source files (MkDocs)
โโโ scripts/ # Utility and automation scripts
โโโ .github/ # GitHub-specific configuration
โโโ package.json # Root workspace configuration
The repository includes a GitHub Actions workflow (.github/workflows/deploy-aws.yml) that builds the PWA and deploys it to AWS S3, fronted by CloudFront.
Required AWS resources:
- S3 bucket (static site hosting)
- CloudFront distribution (CDN, HTTPS, custom error pages for SPA routing)
- GitHub OIDC identity provider in IAM
- IAM role with S3 put/delete and CloudFront invalidation permissions
Required GitHub repository variables (Settings โ Secrets and variables โ Actions โ Variables):
| Variable | Description |
|---|---|
AWS_ROLE_ARN |
ARN of the IAM deploy role |
AWS_REGION |
AWS region of the S3 bucket |
S3_BUCKET_NAME |
Name of the S3 bucket |
CLOUDFRONT_DISTRIBUTION_ID |
CloudFront distribution ID |
CLOUDFRONT_DOMAIN |
(optional) Domain for post-deploy smoke test |
The workflow runs automatically on push to main and can be triggered manually via workflow_dispatch. See docs-src/deployment.md for the full step-by-step setup guide, including the IAM policy JSON and CloudFront configuration.
Contributions are welcome! Please read CONTRIBUTING.md for guidelines. Note that this is primarily a hobby project for my own benefit - if there's something you'd like to see improved please LMK, but also know that maintaining Scryglass isn't my day job.
Card images and data are provided by Scryfall. Scryglass respects Scryfall's API guidelines by rate-limiting requests, caching aggressively, and including a descriptive User-Agent header. See our ROBOT_ETHICS.md policy.
This project is licensed under a GPL License.
Scryglass is unofficial Fan Content permitted under the Fan Content Policy. Not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. ยฉWizards of the Coast LLC.