A TypeScript Pokémon matchup evaluator for ranking team-vs-team options from JSON teams, Showdown export text, PKHeX-compatible save files, named trainers, or an interactive terminal UI.
Designed for practical matchup planning: fast enough for iteration, detailed enough for actionable decisions.
- Highlights
- Repository status
- Getting started
- For non-CLI users
- Packaged app builds (no Node.js needed)
- Validation
- Quick usage
- CLI options
- TUI keybindings
- TUI full guide
- Data model
- Programmatic API
- Project structure
- Contributing
- Release hygiene
- Accuracy and mechanics
- Roadmap
- Loads Pokémon/move/item/ability data from configurable sources.
- Builds battle-ready stats from
species,level,nature,ivs, andevs. - Scores matchups using:
- type effectiveness
- damage ranges and KO odds
- turn order (speed + priority)
- weather / terrain / screens / hazards
- setup discovery with short lookahead
- Supports both CLI and Ink-based TUI workflows.
- Exposes a reusable TypeScript API.
- Runtime: Node.js 22+
- Language: TypeScript (ESM)
- CI workflows:
.github/workflows/validate.yml.github/workflows/mechanics-validation.yml
Requirements:
- Node.js 22+
- npm
Install dependencies:
npm installShow CLI help:
npm start -- --helpIf you do not work in terminals often, use the guided TUI flow:
- Open this project folder in VS Code.
- Open the built-in terminal (
Terminal→New Terminal). - Run:
npm install
npm start -- --tui- In setup, choose your sources (team file: JSON/Showdown, save, trainer) and select
doublesorsingles. - In editor, press
cto calculate. - In results, press
hfor help andbto go back and edit.
Quick keys:
Enter: confirm / continueArrow keys: move selectione: edit selected fieldc: calculateq: quit
Starter files you can edit directly:
If you download packaged artifacts from Releases, users do not need Node.js or npm.
Recommended for most users: portable runtime builds (full app, including TUI). On Windows, double-click poke-eval.cmd to open the guided TUI.
Portable artifact layout:
poke-eval-portable-<platform>-<arch>.tar.gz- extracted folder:
portable-<platform>-<arch>/ - launcher files:
poke-eval,poke-eval.cmd,poke-eval.ps1 - bundled runtime + app files
Nightly builds:
- A nightly workflow publishes fresh artifacts and single-file binaries in GitHub Actions:
.github/workflows/nightly-portable-builds.yml
Run examples after download (portable build):
- macOS / Linux:
chmod +x ./poke-eval./poke-eval
- Windows:
- double-click
poke-eval.cmd - or run
poke-eval.cmdfrom Command Prompt
- double-click
Alternative: single-file binaries (CLI-focused):
Expected artifacts:
- Windows:
poke-eval-win-x64.exe - macOS Intel:
poke-eval-macos-x64 - macOS Apple Silicon:
poke-eval-macos-arm64 - Linux x64:
poke-eval-linux-x64
Run examples after download:
- Windows:
./poke-eval-win-x64.exe --my=my-team.json --enemy=enemy-team.json --json
- macOS / Linux:
chmod +x ./poke-eval-macos-arm64./poke-eval-macos-arm64 --my=my-team.json --enemy=enemy-team.json --json
Current limitation:
- Single-file binaries currently support file-driven CLI execution.
- TUI mode (
--tui) is not enabled in single-file binaries because the current Ink/Yoga TUI stack is not compatible with pkg's single-file snapshot runtime. - Use portable runtime builds for packaged TUI usage.
For maintainers building local binaries:
npm run package:portable
npm run package:portable:all
npm run package:bin:linux-x64
npm run package:bin:macos-x64
npm run package:bin:macos-arm64
npm run package:bin:win-x64Build all targets:
npm run package:portable:all
npm run package:bin:allRun local quality gates before pushing changes:
npm run validate:typecheck
npm run validate:test
npm run validate:accuracy
npm run validate:bench
npm run validate:allvalidate:all runs typecheck + tests + calculator-accuracy spot checks + benchmark validations.
All commands assume repository root.
Team JSON vs team JSON:
npm start -- --my=my-team.json --enemy=enemy-team.jsonShowdown export text vs Showdown export text:
npm start -- --my=my-team.txt --enemy=enemy-team.txtTeam JSON vs named trainer:
npm start -- --my=my-team.json --game=sv --trainer=nemonaSave file vs team JSON:
npm start -- --my-save=/path/to/main.sav --enemy=enemy-team.jsonTUI mode:
npm start -- --tui--my=<path>your team file (JSON array or Showdown export text)--my-save=<path>your team from PKHeX-compatible save file--enemy=<path>enemy team file (JSON array or Showdown export text)--enemy-builderbuild enemy team interactively--game=<id>+--trainer=<name>load trainer team--against-trainer=<game>:<trainer>shorthand
--data-source=showdown|pokeapi--trainer-source=littleroot|pokeapi
--format=singles|doubles--mode=casual|competitive|custom--gen=<1-9|alias>--lookahead=1|2|3--allow-switching--role-weight=<number>--defensive-weight=<number>--opponent-risk-weight=<0..1>--weather=sun|rain|sand|snow|none--terrain=electric|grassy|misty|psychic|none
Mode behavior:
casual: shorter horizon, forgiving risk profilecompetitive: deeper horizon, stronger risk weightingcustom: use explicit numeric flags
Format behavior:
singles: 1v1 matchup evaluationdoubles: 2v2 lead-pair evaluation with support-tempo heuristics
--my-reflect--my-light-screen--enemy-reflect--enemy-light-screen--my-spikes=0..3--my-stealth-rock
--json--interactiveor--tui--help
Notes:
--myand--my-saveare mutually exclusive.- Generation alias parsing lives in src/utils.ts.
Full end-user guide (setup wizard, game codes, field formats, workflows): docs/TUI_GUIDE.md
Implementation entry: src/tui/ui.tsx
Setup phase:
Enter: next/confirmEscorCtrl+C: exit
Setup includes a battle-gimmicks policy prompt:
Default by generation: Gen 6-7 Mega, Gen 8 Dynamax, Gen 9 TeraDisable all: disables Mega Evolution, Dynamax, and Terastallization in evaluation
Setup also includes a gimmick timing control prompt:
Manual: uses team-set gimmick flags directly (megaForm/teraType/dynamax)Auto: engine chooses timing and evaluates against opponent best-response gimmick branches
Editor phase:
Arrow keys: navigate selectione: edit selected fieldEnter: commit editEsc: cancel edito: toggle editing side (your team / enemy team)a: add slotx: delete slotp: estimate IV/EVs: save current team JSONc: calculateqorCtrl+C: quit
Results/help phase:
h: open/close fullscreen helpm: close fullscreen helpb: back to editorr: recomputeqorCtrl+C: quit
Each team is an array of PokemonSet records.
[
{
"species": "Garchomp",
"level": 50,
"nature": "Jolly",
"ability": "Rough Skin",
"item": "Choice Scarf",
"megaForm": "Mega",
"teraType": "Ground",
"dynamax": false,
"status": null,
"boosts": { "atk": 0, "spe": 0 },
"ivs": { "hp": 31, "atk": 31, "def": 31, "spa": 31, "spd": 31, "spe": 31 },
"evs": { "hp": 0, "atk": 252, "def": 0, "spa": 0, "spd": 4, "spe": 252 },
"moves": ["Earthquake", "Dragon Claw", "Swords Dance", "Protect"]
}
]Mechanics gating is generation-aware during build/evaluation:
megaFormis only applied when loaded generation is Gen 6-7.dynamaxis only applied when loaded generation is Gen 8.teraTypeis only applied when loaded generation is Gen 9.
Canonical type definition: src/types.ts
Sample files:
Public exports are centralized in src/index.ts.
Detailed API reference: docs/API.md
- src/main.ts: executable entry
- src/cli.ts: argument parsing and orchestration
- src/interactive.ts: prompts, pretty output, TUI launcher
- src/tui/index.ts: Ink bootstrap
- src/tui/ui.tsx: TUI coordinator and input flow
- src/tui/views.tsx: TUI screens/components
- src/tui/setup.ts: setup-question composition
- src/tui/model.ts: shared TUI models/constants
- src/tui/utils.ts: TUI helpers and field parsing
- src/data.ts: species/move/item/ability loading
- src/pokemon.ts: stat and battle Pokémon construction
- src/evaluation.ts: matchup scoring engine
- src/trainers.ts: trainer team fetching/adapters
- src/estimation.ts: IV/EV spread estimation
- src/save-import.ts: PKHeX save-file party import
- src/utils.ts: parsing and normalization helpers
- src/types.ts: shared contracts
Contributor workflow: CONTRIBUTING.md
- Changelog: CHANGELOG.md
- Release process and checklist: docs/RELEASE_PROCESS.md
- Mechanics assumptions and known approximations: docs/MECHANICS_VALIDATION.md
- Accuracy verification workflow: docs/ENGINE_ACCURACY_VERIFICATION.md
Future planning and priorities: ROADMAP.md
- This is a practical evaluator, not a full turn-perfect simulator.
- Recommendations are uncertainty-aware and based on known/provided sets.
npm testcurrently aliases to CLI startup.