Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

300 Commits

Repository files navigation

Lunidex logo

Lunidex

A local-first Pokémon companion for players, trainers, and TCG collectors.

Live appCINode.js 22Next.js 16React 19TypeScript 5MobileGitHub stars

Live app · Repository · Issues

Overview · Features · Get started · Architecture · Configuration · Deployment

Lunidex desktop Pokédex and collection dashboard

English · Français · Español · Deutsch · Italiano · 日本語 · 한국어 · 中文 · Português

Overview

Lunidex is a free, open-source npm-workspaces monorepo that brings a complete Pokédex, team-building tools, Pokémon TCG collection tracking, and personal progress into one focused workspace.

The web app covers 1,025 Pokémon across nine generations and supports eight interface languages: English, French, Spanish, German, Italian, Japanese, Korean, and Simplified Chinese. Portuguese is currently available as a README translation only.

It works without an account. Personal state is stored locally by default, while optional Neon Auth and Neon PostgreSQL integrations add accounts, cloud sync, public profiles, friends, leaderboards, battle rooms, and server-backed features.

Note

Lunidex is an unofficial, non-commercial fan project. Pokémon data, names, characters, and imagery belong to Nintendo, Game Freak, Creatures, and The Pokémon Company. Lunidex is not affiliated with or endorsed by them.

Lunidex mobile Pokédex view

Features

AreaWhat you can do
Pokédex and referenceBrowse and filter all 1,025 Pokémon; inspect stats, types, abilities, moves, evolutions, forms, encounters, sprites, and localized species data. Search moves, abilities, and items.
Team and battle labBuild teams of up to six, analyze type and move coverage, score team synergy, compare up to three Pokémon, explore the 18-type chart, plan EVs and IVs, calculate breeding outcomes, and simulate Gen 9 battles.
Progress and playTrack favorites, captures, Living Dex progress, activity, badges, and quiz statistics. Play six quiz modes, track a Nuzlocke run, share teams with read-only links, and import/export Showdown-compatible teams.
Pokémon TCG workspaceBrowse cards and sets, track collection and wishlist progress, compare cards, save searches and notes, inspect set completion, research prices, and build 60-card decks.
Local-first workflowKeep using the app without an account. Web state persists in IndexedDB, mobile state uses AsyncStorage, and the PWA caches its shell and selected upstream resources for resilient repeat visits.
Mobile companionRun the Expo app on iOS, Android, or the web with shared API clients, types, Zustand state, persistence contracts, and translations from @primedex/core.

Explore the app

The locale prefix can be changed from en to any supported language.

SurfaceRoute
Pokédex/en/pokedex
Team builder/en/team
Type chart/en/types
Pokémon quiz/en/quiz
TCG catalog/en/tcg
TCG collection/en/tcg/collection
Personal dashboard/en/dashboard

Get started

Prerequisites

  • Node.js 22
  • npm and the committed package-lock.json
  • Git

Clone the repository, install the workspace dependencies, and start the web app:

git clone https://github.com/teefloo/Lunidex.git
cd Lunidex
npm ci
npm run dev

Open http://localhost:3000. The locale proxy redirects an unprefixed URL to a supported locale such as /en, using the primedex-lang cookie or the browser language when available.

Important

Development and production builds intentionally use webpack: npm run dev runs next dev --webpack, and npm run build runs next build --webpack. Keep the flag even though the Next.js configuration also declares a Turbopack root.

Common commands

CommandDescription
npm run devStart the Next.js development server on port 3000.
npm run buildCreate a production build.
npm run startServe the production build.
npm run lintLint the web, core, and mobile source files.
npm run typecheckType-check the web application without emitting files.
npm run test -- --runRun the Vitest suite once.
npx vitest run path/to/file.test.tsRun one focused test file.
npx tsc --project packages/core/tsconfig.json --noEmitType-check the shared core package.
npm run typecheck --workspace=@primedex/mobileType-check the Expo app.

Mobile app

The Expo companion lives in apps/mobile. It consumes @primedex/core instead of duplicating API, domain, persistence, or localization logic.

npm run start --workspace=@primedex/mobile

Use the Expo prompt to open iOS, Android, a web preview, or Expo Go. Native development requires the relevant platform tooling; the app remains local-first when its optional Neon variables are absent.

See the mobile README for supported screens, platform adapters, and mobile-specific setup.

Configuration

No environment variables are required to browse the Pokédex or use local collections. Copy .env.example to .env.local only when enabling an optional integration:

cp .env.example .env.local
VariableScopePurpose
NEXT_PUBLIC_APP_URLWeb / publicCanonical site URL and the base URL used by shared clients. Defaults to https://lunidex.app.
NEXT_PUBLIC_NEON_AUTH_URLWeb / publicPublic Neon Auth endpoint used by the browser client.
NEON_AUTH_BASE_URLServer-onlyNeon Auth base URL used by the /api/auth proxy.
NEON_AUTH_JWKS_URLServer-onlyJWKS endpoint used to verify Neon Auth tokens.
NEON_AUTH_COOKIE_SECRETServer-onlySecret used to protect the server-side auth cookie.
NEON_DATABASE_URL / DATABASE_URLServer-onlyNeon PostgreSQL connection string. DATABASE_URL is supplied by the Vercel Neon integration; NEON_DATABASE_URL is useful locally.
EXPO_PUBLIC_NEON_AUTH_URLMobile / publicPublic Neon Auth endpoint for the Expo app.
EXPO_PUBLIC_APP_URLMobile / publicDeployed Lunidex API URL used by the Expo app.
NEXT_PUBLIC_GOOGLE_VERIFICATIONWeb / publicOptional Google Search Console verification value.
NEXT_PUBLIC_ENABLE_AGENTATIONDevelopmentEnables the Agentation UI-review toolbar when set to true.
NEXT_PUBLIC_VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECTWeb pushOptional push-subscription configuration for TCG notifications; keep the private key and subject server-side.

Tip

Keep connection strings, JWKS configuration, cookie secrets, and VAPID private keys server-side. Never put them in NEXT_PUBLIC_*, EXPO_PUBLIC_*, source files, logs, or commits.

Without Neon configuration, favorites, captures, teams, filters, quiz progress, TCG state, and preferences stay on the device. The active runtime uses Neon; SUPABASE_DB_URL is retained only for the one-time migration scripts and is not an application runtime variable.

Enable Agentation during development

Add this value to .env.local and restart the dev server:

NEXT_PUBLIC_ENABLE_AGENTATION=true

The development helper runs on http://localhost:4747; its origin and CSP support are already configured.

Architecture

.
├── src/ Next.js 16 / React 19 web application
├── packages/core/ @primedex/core: shared API clients, types, state, i18n, and helpers
├── apps/mobile/ Expo 57 / React Native companion
├── neon/migrations/ Active Neon PostgreSQL application schema
├── supabase/ Archived source migrations and compatibility material
├── scripts/neon/ Controlled export, import, and verification scripts
└── public/ PWA icons, screenshots, and static assets
Web (Next.js App Router)
├── Server and client route components
├── TanStack Query ──▶ @primedex/core API clients ──▶ PokéAPI + TCGdex
├── Zustand ──▶ IndexedDB persistence
└── Server API routes ──▶ Neon Auth + Neon PostgreSQL
Mobile (Expo Router)
├── Native screens and providers
└── @primedex/core ──▶ AsyncStorage + the same domain logic

Key boundaries:

  • UI: Next.js 16 App Router, React 19, TypeScript 5, Tailwind CSS 4, Base UI, and Framer Motion; Server Components are the default and interactive leaves opt into client rendering.
  • Shared core: business logic, API clients, domain types, i18n bundles, Zustand state, and pure helpers are kept UI-free so web and mobile can share them.
  • Data access: remote requests go through the centralized API façade and TanStack Query rather than ad hoc component fetches.
  • Persistence: the web uses IndexedDB; native builds use AsyncStorage through platform adapters. Persisted state stores compact IDs and user-owned primitives, not full upstream API responses.
  • Localization: locale-prefixed routes and lazy translation bundles support en, fr, es, de, it, ja, ko, and zh.
  • Compatibility: Lunidex is the visible brand, while package names such as @primedex/core and storage keys retain their historical identifiers so existing data and mobile builds continue to work.

Data sources and attribution

SourceUsed for
PokéAPI REST and GraphQLPokémon, species text, stats, types, moves, abilities, evolutions, encounters, and localized names.
TCGdexPokémon TCG cards, sets, rarities, catalog data, and card images.
PokéAPI spritesPokémon and item sprites used throughout the interface.
NeonOptional PostgreSQL storage, Neon Auth, cloud synchronization, profiles, social features, and server-side metrics.

The application revalidates upstream catalog data and keeps the personal workspace separate from those public sources. Pokémon intellectual property is not covered by the repository's MIT license; see LICENSE for the exact scope.

Deployment

Lunidex is configured for Vercel and can also run on a host that supports the Next.js server runtime and image optimization.

npm run build
npm run start

For Vercel:

  1. Import teefloo/Lunidex into a Vercel project.
  2. Configure the Neon Auth values and the server-side database connection in Preview and Production.
  3. Deploy with the standard Next.js settings. The committed vercel.json intentionally stays minimal.

For the migration history and the controlled Neon scripts, see docs/neon-migration.md.

Related docs

About

PrimeDex: A high-performance Pokemon Gaming Dashboard built with Next.js 15, PokéAPI, and Framer Motion.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages