Open source TCG collection tracker. Free, self-hostable, server-rendered.
Track your card collection across 8 TCGs. Know your total value. Export your data. Clone, set API key, deploy in 5 minutes.
TCGVault is a self-hostable web app for tracking your trading card game collection. You deploy it with your API key from tcgpricelookup.com set as an environment variable — the key lives on the server, never in the browser. Your collection is stored in your browser's localStorage. No account, no cloud database.
- 8 TCGs: Pokemon, MTG, Yu-Gi-Oh!, Lorcana, One Piece, Star Wars: Unlimited, Flesh and Blood, Pokemon Japan
- Live pricing: Real-time prices via TCG Price Lookup API, fetched server-side
- Secure: API key in
.envon the server — never exposed to the browser - Export: Download your collection as JSON or CSV
- Self-hostable: Deploy to Cloudflare Pages, Vercel, Netlify, or run locally
- Open source: MIT licensed, PRs welcome
- i18n: Available in English (default) and Japanese (
/ja/)
Get a free API key at tcgpricelookup.com/pricing — 200 requests/day, no credit card required.
One-click deploy (set TCG_API_KEY in environment variables during setup):
git clone https://github.com/TCG-Price-Lookup/tcgvault
cd tcgvault
cp .env.example .env
# Add your TCG_API_KEY to .env
npm install
npm run devOpen http://localhost:4321 and start tracking your collection.
| Variable | Description |
|---|---|
TCG_API_KEY |
Your TCG Price Lookup API key (required) |
Create .env from the example:
cp .env.example .envThen edit .env and replace your_api_key_here with your actual key.
TCGVault uses Astro hybrid output with the Cloudflare Pages adapter:
- Landing pages (
/,/about) are pre-rendered as static HTML - API routes (
/api/search,/api/card,/api/batch,/api/games) run server-side and call the TCG Price Lookup API usingTCG_API_KEYfrom the environment - The React app (
/app) calls these API routes viafetch()— no SDK in the browser - Your collection is stored in
localStorageas JSON
Your Browser
├── localStorage: collection
└── fetch() → /api/search (your server)
└── TCGVault Server → tcgpricelookup.com (TCG_API_KEY from env)
API key in browser: never
| Layer | Technology |
|---|---|
| Framework | Astro 5 — hybrid output |
| Adapter | @astrojs/cloudflare |
| UI | React 19 — interactive islands |
| Styling | Tailwind CSS 4 via @tailwindcss/vite |
| Prices | @tcgpricelookup/sdk — server-side only |
| Language | TypeScript (strict mode) |
| Deploy | Cloudflare Pages (primary), Vercel, Netlify |
tcgvault/
├── .env.example # Copy to .env, add TCG_API_KEY
├── astro.config.mjs # hybrid output + cloudflare adapter
├── src/
│ ├── styles/global.css
│ ├── layouts/BaseLayout.astro
│ ├── pages/
│ │ ├── index.astro # Landing page (prerendered)
│ │ ├── app.astro # Collection tracker (prerendered shell)
│ │ ├── about.astro # How it works (prerendered)
│ │ └── api/ # Server-rendered API routes
│ │ ├── search.ts # GET /api/search?q=...&game=...
│ │ ├── card.ts # GET /api/card?id=...
│ │ ├── batch.ts # POST /api/batch { ids: string[] }
│ │ └── games.ts # GET /api/games
│ ├── components/
│ │ ├── Header.astro
│ │ ├── Footer.astro
│ │ ├── Hero.astro
│ │ ├── Features.astro
│ │ ├── CTA.astro
│ │ └── app/ # React islands
│ │ ├── App.tsx
│ │ ├── SearchBar.tsx
│ │ ├── CardSearchResults.tsx
│ │ ├── CollectionList.tsx
│ │ ├── CardDetail.tsx
│ │ ├── GameFilter.tsx
│ │ ├── ExportMenu.tsx
│ │ ├── EmptyState.tsx
│ │ └── Settings.tsx
│ └── lib/
│ ├── storage.ts # localStorage wrapper (collection only)
│ ├── client.ts # Placeholder (SDK used server-side only)
│ └── types.ts # Shared TypeScript types
└── public/
├── favicon.svg
└── robots.txt
// Keys used
"tcgvault:collection" → CollectionItem[]
// CollectionItem
{
id: string // Card UUID from API
name: string
game: string // e.g. "pokemon", "mtg"
set: string // Set name
setCode: string // Set slug
number: string // Card number
quantity: number
condition: "near_mint" | "lightly_played" | "moderately_played" | "heavily_played" | "damaged"
addedAt: string // ISO timestamp
cachedPrice?: number
imageUrl?: string
}PRs and issues are welcome. Please open an issue first for major changes.
- Fork the repo
- Create a feature branch:
git checkout -b feat/my-feature - Commit your changes
- Open a pull request
- tcgfast.com — TCG Price Lookup API docs and tools
- tcgpricelookup.com — The underlying price API
- @tcgpricelookup/sdk — Official JavaScript SDK
- TCG Discord Bot — Price lookups in Discord
- nextjs-tcg-starter — Next.js starter template
- More tools — GitHub organization
MIT — see LICENSE.
Built with TCG Price Lookup API · Docs · GitHub