A catalogue of all 213 personas from Persona 3 Reload: arcana, stats, elemental affinities and skills, plus fusion tools, an arcana / Social Link guide and a team analyzer, with artwork mirrored locally. A pure static single-page app built on Vite + React 19 + TypeScript + Tailwind v4, forked from luyluish/persona-compendium. There is no runtime backend: the dataset is generated at build time and served as static files. Installable as a PWA and usable offline after the first visit.
- Catalog - grid of all 213 personas with search, sortable columns, and paginated "Load more". Filters: arcana, source (base / DLC / special-fusion), elemental affinity (two stackable element + relation conditions), level range, origin, favorites, no-weakness, and not-yet-collected. Applied filters show as removable chips, and the data filters live in the URL so a filtered view is shareable and survives a reload.
- Command palette -
Cmd/Ctrl-K(or the navbar search button) opens a fuzzy finder over every persona, arcana and section page; arrow keys and Enter navigate without the mouse. - Persona detail - modal with description, a stat radar plus value bars, an
elemental affinity matrix (all nine elements, glyph-coded so it reads without
colour), learned skills (element icon and effect), fusion recipes with an
expandable multi-step "full chain" (cheapest, or buildable from your
collection), and, where relevant, its Theurgy fusion-spell pair. Opens with a
view transition and is deep-linkable at
/persona/<query>. - Fusion - forward result in Compare (two personas -> product, click to open it), a multi-step recipe finder, a 22x22 arcana fusion matrix, a special-recipe reference, the seven protagonist Theurgy fusion spells and each party member's Theurgy skill (base and its evolved form).
- Arcana / Social Link -
/arcanaindex and per-arcana pages with the confidant, its personas, and the arcana's ultimate persona plus how it unlocks. - Skills -
/skillscatalog with owners, effects and a "how skills work" guide. - Bosses -
/bossesreference of the 57 story bosses with their weaknesses / resistances; each weakness links to the skills that exploit it. - Requests -
/requestslist of all 101 Elizabeth's Requests with rewards, filterable by reward type and by deadline / missable. - Team - pick a party and see defensive coverage and offensive damage types.
- Collection tracker - mark personas as collected; progress shows in the hero and drives the not-collected filter.
- Dark mode - a "Dark Hour" theme following the system setting, with a toggle that cuts over instantly (no cross-fade). An offline-capable service worker caches the app; when a new version deploys it prompts to reload.
State is client-side only (favorites, collection, theme in localStorage).
Static pipeline, no server process at runtime:
frontend/data/compendium.tsv 213 rows, tab-separated, one header, source of truth
|
| build step: node scripts/generate-personas.mjs (runs on predev / prebuild)
v
frontend/public/personas.json generated build artifact
|
| bundled by `vite build`
v
frontend/dist/ -> static host / CDN --(fetch /personas.json)--> browser SPA
art: frontend/public/personas/*.webp 213 files (~7.7 MB), shipped in repo
frontend/data/compendium.tsvis the single source of truth for personas. The build stepfrontend/scripts/generate-personas.mjsparses it into a typedfrontend/public/personas.json, which the SPA fetches as/personas.json. Skills are a second dataset,frontend/public/skills.json(generated byscripts/generate-skills.mjsand committed), fetched as/skills.json. Bosses (generate-bosses.mjs) and Elizabeth's requests are two more committed JSON datasets underpublic/, fetched the same way.frontend/- SPA with a browser (hero, search, filters, card grid, compare and team modes), a persona modal,/arcana(fusion matrix, special recipes, Theurgy) and per-arcana pages, and/skills. Arcana and element lists are derived from the data. Persona art lives underfrontend/public/personas/(*.webp) and ships with the repo.- Routing is client-side:
/persona/<query>,/arcana/<slug>and/skillsopen directly via the History API. On a static host this works through an SPA-fallback rewrite toindex.html; unknown paths render a client-side 404. - Client state is limited to
localStorage(favorites, collection tracker, theme). No accounts, auth, database or API. frontend/public/sw.jsis a dependency-free service worker (registered in production only) that caches the shell, data and viewed artwork for offline use;public/theme-init.jsapplies the saved theme before first paint.
Requires Node 22+. Python is not needed.
cd frontend
npm install
# dev server with hot reload (predev regenerates personas.json first)
npm run dev # http://localhost:5173
# production build (prebuild regenerates personas.json)
npm run build # output in frontend/dist
# preview the production build locally
npm run previewYou can regenerate the data on its own with npm run generate:data.
End-to-end smoke tests (Playwright) run against the static production build
served by vite preview - no Python and no backend. e2e/compendium.spec.ts
covers browsing, filters, fusion, the command palette and routing;
e2e/a11y.spec.ts runs @axe-core/playwright over the main screens and open
dialogs and fails on any violation:
cd frontend
npm run test:e2eLint (ESLint with typescript-eslint, react-hooks and jsx-a11y) runs on
npm run lint. CI (GitHub Actions) runs three jobs: frontend
(typecheck + lint + build), e2e, and lighthouse (Lighthouse-CI against the
built dist with performance budgets - CLS and LCP regressions fail the run).
Data integrity is enforced at generation time: the generators fail the build on
a duplicate or empty query, a bad TSV column count, or upstream schema drift
(skill / boss match counts out of range).
The app is a static site. The included render.yaml deploys it to
Render:
- build:
cd frontend && npm ci && npm run build - publish:
frontend/dist - SPA-fallback rewrite of
/*to/index.html - security headers:
Content-Security-Policy,Cross-Origin-Opener-Policy,Cross-Origin-Resource-Policy,X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: no-referrer,Permissions-Policy,Strict-Transport-Security
The same build and publish settings work on Vercel, Netlify or Cloudflare Pages; each needs an equivalent SPA rewrite and the same security headers.
BSD 3-Clause, see LICENSE. Persona and Megami Tensei are trademarks of Atlus; the game data and artwork belong to Atlus.