A web application for maimai DX (music arcade game) providing rating calculators, song data, and community features such as tags, comments, and aliases.
This is a Turborepo monorepo using pnpm as the package manager.
apps/
├── web/ React 19 + Vite SPA (UnoCSS, MUI, wouter, TanStack Query)
├── backend/ Hono API server (oRPC, Drizzle ORM, PostgreSQL, Better Auth)
└── functions/ Cloudflare Workers (edge endpoints)
packages/
├── dxdata/ Pre-annotated maimai DX song & sheet metadata
└── tsconfig/ Shared TypeScript base configuration
scripts/
└── annotator/ Generates annotated song metadata from various sources
-
apps/web— The main frontend, serving both web and iOS (via WKWebView) variants. Built with React 19, Vite, UnoCSS, Material-UI 5, and shadcn/ui. Supports 4 languages (en, ja, zh-Hans, zh-Hant) via i18next, with an in-browser SQLite database (sql.js) for offline song data. -
apps/backend— The API server built on Hono. Uses oRPC for type-safe API contracts (defined with Zod), Drizzle ORM with PostgreSQL 16 for persistence, and Better Auth for authentication (email/password, Google/GitHub OAuth, passkeys). -
apps/functions— Cloudflare Workers edge functions built on Hono, mirroring select backend endpoints for lower latency.
-
packages/dxdata— The legacy compatibility snapshot and TypeScript helpers. New native clients read the published catalog API; this package remains while existing web and renderer consumers migrate. -
packages/tsconfig— Shared TypeScript configuration used across all apps and packages.
GET /api/v1/dxdata returns the complete current catalog and its metadata in
one schema-versioned, null-free document. The producer stores immutable bodies
in PostgreSQL and atomically advances the production-v1 pointer; the API never
reconstructs the document per request or exposes stored provenance.
The backend reads dxdata.catalog_publications, dxdata.catalog_snapshots, and
dxdata.catalog_build_runs; identity translation joins the current
dxdata.catalog_run_songs and dxdata.catalog_run_sheets memberships to
dxdata.canonical_songs, dxdata.canonical_sheets, and
dxdata.song_source_mappings.
The endpoint supports GET, metadata-only HEAD, strong ETag validators,
and If-None-Match. Successful responses are public and use separate browser
and CDN stale-while-revalidate policies. Errors are no-store. Cloudflare
Cache Rules for the catalog and arcade-catalog paths are owned by the
infrastructure Terraform repository, leaving this application repository with
a single deployment authority.
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite, UnoCSS, MUI 5, wouter, TanStack Query |
| Backend | Hono, oRPC, Drizzle ORM, PostgreSQL 16, Better Auth |
| Edge | Cloudflare Workers, Hono |
| Language | TypeScript 5.9, ESM throughout |
| Monorepo | Turborepo, pnpm 10 |
| Linting | oxlint + oxfmt |
| Testing | Vitest |
| Observability | PostHog, Sentry |
- Node.js 25.9.0
- pnpm 10.30.3+
- Docker (for running PostgreSQL locally)
pnpm installpnpm --filter @gekichumai/backend db:upCopy the example env files and fill in the required values:
cp apps/backend/.env.example apps/backend/.env.localKey variables:
DATABASE_URL— PostgreSQL connection string (default:postgres://postgres:postgres@localhost:5432/dxrating)BETTER_AUTH_SECRET— Auth secret key
pnpm devThis starts all apps concurrently:
- Web: http://localhost:5173
- Backend: http://localhost:3000
pnpm buildpnpm lint # Check with oxlint
pnpm lint:fix # Auto-fix lint issues
pnpm format # Format with oxfmt
pnpm format:check # Check formattingpnpm --filter @gekichumai/backend test # Backend integration tests (requires PostgreSQL)
pnpm --filter @gekichumai/dxrating-web test # Web unit tests- Web — Cloudflare Pages
- Backend — Docker container deployed via Coolify
- CI/CD — GitHub Actions auto-tags versions on push to
mainand triggers deployments
If you find a vulnerability in the repository, please email the organization owner (vulnerability@dxrating.net). We kindly ask you not to disclose the detail of the vulnerability to the public before we have released a fix. Thanks for making DXRating a better site!
This project is made possible by the following contributors. Contributions are always welcome!