A modular, data-driven Pokémon team builder built with vanilla JavaScript, Vite, and Pico CSS.
The application is designed around reusable generation data files, allowing new Pokémon generations to be added primarily through JSON rather than JavaScript changes.
- Data-driven generation support
- Offline-capable
- Modular ES Modules architecture
- Team defensive matchup analysis
- Version-exclusive filtering
- Trade evolution filtering
- Final evolution filtering
- Local sprite support
- Responsive Pico CSS interface
Current Stable Version: v1.0.0
Generation I is complete and available as the first stable release.
The next planned release is v1.0.1, a maintenance release focused on dependency updates, tooling improvements, and minor cleanup. No major application architecture or new Pokémon generations are planned for this patch release.
Development after v1.0.1 will begin the v1.1.0 architecture update, migrating the application to Next.js with API routes and a SQLite-backed data model.
This will establish the foundation for additional generations, generation-aware Pokémon data, forms, Mega Evolutions, and other mechanics without relying on increasingly complex generation-specific JSON files.
See TODO.md for the full development roadmap and planned v1.1.0 migration.
This project is licensed under the MIT License.
- ✅ Use, copy, modify, merge, publish, distribute
- ✅ No attribution required (but appreciated)
- ❌ No warranty included — use at your own risk
All Pokémon names, images, and data are © Nintendo, Game Freak, and The Pokémon Company.
This project references publicly available sprite assets hosted by the PokeAPI sprite repository for educational and fan use only.
This project does not distribute or claim ownership of any Pokémon intellectual property.
- Frontend: HTML5 + Vanilla JavaScript (ES Modules)
- Styling: Pico CSS + application-specific CSS
- Bundler: Vite
- Data: JSON
- Documentation: JSDoc
- Linting: ESLint, Stylelint, html-validate
- Accessibility: axe-core CLI
- Pico.css: 2.1.1
- ESLint: 9.28.0
- Node.js: 22.16.0
- NPM: 10.9.2
- Git CLI
- Optionally: VS Code
This project targets the last 2 versions of:
- Chrome
- Firefox
- Safari
- Edge
Defined via Browserslist for browser compatibility and future tooling.
- Clone the Repository
git clone https://github.com/jennifert/pokemon-builder-public.git
cd pokemon-builder-public- Download Sprites Locally
Sprites are not bundled with this project due to copyright.
Instead, download them manually from the PokeAPI sprites repo:
git clone https://github.com/PokeAPI/sprites.gitThen copy the Generation I sprite folder into your local project directory:
sprites/sprites/pokemon/versions/generation-i
Paste them under:
pokemon-builder/public/img/
You should now have:
pokemon-builder-public/public/img/generation-i
- Install Dependencies
npm install- Start Development Server
npm run dev- Open in Browser
http://localhost:5173
.
├── index.html # Main application page
│
├── src/
│ ├── js/
│ │ ├── main.js # Application entry point
│ │ ├── ui.js # UI events and application flow
│ │ ├── state.js # Shared DOM references and application state
│ │ ├── fetch.js # Loads Pokémon generation data
│ │ ├── party.js # Manages the player's party
│ │ ├── team.js # Calculates team defensive analysis
│ │ ├── display.js # Renders analysis tables and UI output
│ │ └── type-utils.js # Pokémon type-analysis utilities
│ │
│ └── css/
│ ├── pico.min.css # Pico CSS framework (vendor file)
│ └── style.css # Project-specific styles
│
├── public/
│ ├── data/
│ │ ├── generations.json # Available Pokémon generations
│ │ ├── gen1.json # Generation I game and Pokémon data
│ │ ├── gen2.json # Generation II data (future support)
│ │ └── ... # Future generation data
│ │
│ └── img/
│ ├── generation-i/ # Generation I sprites
│ └── ... # Future generation sprites
│
├── docs/ # Generated JSDoc documentation
│
├── package.json # Project metadata and npm scripts
├── package-lock.json # Locked dependency versions
├── vite.config.js # Vite configuration (if present)
├── eslint.config.js # ESLint configuration
├── .stylelintrc # Stylelint configuration
├── jsdoc.json # JSDoc configuration
├── README.md # Project overview and usage
└── LICENSE # Project license
The project follows a data-driven design.
Application logic lives under:
src/
Game data lives under:
public/data/
Each supported generation is represented by its own JSON file.
Example:
generations.json
│
▼
Enabled Generation
│
▼
gen1.json
Future:
gen2.json
gen3.json
...
The project separates application logic from Pokémon data.
src/contains reusable JavaScript modules.public/data/contains generation-specific game data.- Adding a new generation should primarily involve creating a new JSON file rather than modifying JavaScript.
style.csscontains only project-specific styles, whilepico.min.cssprovides the base UI framework.
| Command | Description |
|---|---|
npm run dev |
Start the local Vite development server |
npm run build |
Create the production build |
npm run preview |
Preview the production build |
npm run lint |
Run all configured linters |
npm run lint:js |
Run ESLint on JavaScript files |
npm run lint:css |
Run Stylelint on application CSS |
npm run lint:html |
Run html-validate on index.html |
npm run a11y |
Run the local accessibility scan |
npm run a11y:dev |
Run axe-core against the development site |
npm run a11y:prod |
Run axe-core against the production site |
npm run docs |
Generate JSDoc documentation |
TODO.md— Full roadmap and implementation plan- Live API Docs — Auto-generated JSDoc documentation
This project aims to be:
- Data-driven
- Modular
- Easy to understand
- Easy to extend
- Friendly to beginners
- Offline capable
- Free and open source
The project aims to keep Pokémon data separate from application logic so that supporting additional generations primarily involves extending structured data rather than rewriting application behavior.
This project uses JSDoc to generate documentation from code comments.
npm run docsThis will populate the /docs folder with up-to-date HTML documentation.
- Each JS module (like
party.js,team.js) includes detailed descriptions, parameters, and return types - Comments follow the JSDoc standard
Before deploying a release, verify the application locally.
- Start the development server:
npm run dev- In another terminal, run the project checks:
npm run lint
npm run a11y:dev- Create the production build:
npm run build- Confirm the generated
dist/folder contains the expected static site assets.
The public site is deployed as a static site through DigitalOcean.
- Run the local production checks and build.
- Copy the contents of the generated
dist/folder into the private deployment repository. - Commit and push the updated static files.
- DigitalOcean automatically deploys the new commit.
- Verify the production site after deployment.
- Select a Pokémon generation.
- Select a sprite set.
- Select a game version.
- Configure the desired filters.
- Click Show Pokémon.
- Select Pokémon to add or remove them from your party.
- Review the team's defensive matchup table.
Accessibility was reviewed as part of the v0.9 release cycle in preparation for the Generation I stable release.
Accessibility improvements and testing include:
- Semantic HTML landmarks and form controls
- Keyboard-accessible Pokémon selection
- Visible keyboard focus indicators
- Accessible party controls
- ARIA live-region announcements for dynamic interactions
- Semantic defensive matchup table structure
- Decorative sprite handling
- Color contrast testing
- Automated axe-core testing
- Browser accessibility-tree inspection
- Keyboard-only navigation testing
- VoiceOver screen reader testing on macOS
Accessibility testing was also performed against the production deployment.
This project would not be possible without these fantastic community resources:
- Shields.io — For README badges
- Awesome README — For formatting inspiration
- PokeAPI Sprites — Pokémon sprite repository
- Bulbapedia — Mechanics reference and bug documentation
- Serebii.net — Dex data, locations, and availability info


