Sudoky is a local-first Sudoku app built with Next.js + React and Supabase auth/database.
- Email/password authentication with required unique username at sign-up
- Home page with 5 Sudoku difficulty levels (easy, medium, difficult, hard, extrem) in 9x9 format
- In-game timer
- Pause/resume controls
- "Leave game (pause)" behavior with browser-local saved progress
- Score submission after a solved Sudoku
- Leaderboard ranked by points then completion time (username only, no email exposed)
Each solved game gives points based on:
- Difficulty (
easy,medium,difficult,hard,extrem) - Completion time (seconds)
Current formula (in code):
- Easy: base
400, max time bonus300(bonus window3h) - Medium: base
550, max time bonus400(bonus window3h15m) - Hard: base
1300, max time bonus1000(bonus window4h30m) - Bonus scales linearly with remaining time in the difficulty window
- Next.js (App Router)
- React
- TypeScript
- Supabase (
@supabase/supabase-js)
- Install dependencies:
npm install- Add env vars:
cp .env.example .env.localFill .env.local with your Supabase project values:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
- Create DB table and policies in Supabase SQL editor:
- Start dev server:
npm run devOpen http://localhost:3000.
/login: authentication page/: home page (difficulty selection + resume saved game)/game?difficulty=easy|medium|difficult|hard|extrem: Sudoku game/leaderboard: scores ranking
- Saved game state is stored in browser
localStorageundersudoky-active-game. - The leaderboard uses Supabase table
public.scores.
This project is configured for static export + GitHub Pages:
- Next config:
next.config.ts - Workflow:
.github/workflows/deploy-pages.yml
Steps:
- Push your repo to GitHub (default branch
main). - In GitHub repo settings:
Settings->Pages->Build and deployment->Source: GitHub Actions.
- In
Settings->Secrets and variables->Actions->Variables, add:NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
- In Supabase Auth settings, add your Pages URLs to allowed redirects, for example:
https://<your-user>.github.io/<your-repo>/https://<your-user>.github.io/<your-repo>/login/
- Push to
main. The workflow will build and deploy automatically.
Notes:
NEXT_PUBLIC_BASE_PATHis injected automatically in CI as/<repo-name>.- Output is static (
out/) and published by GitHub Pages.
new local version:
docker compose -f supabase/docker-compose.yml up
Init cp supabase/.env.example supabase/.env
Access Supabase Studio on http://localhost:8000 with credentials from supabase/.env.
App schema auto-init behavior (self-hosted Docker):
supabase/docker-compose.ymlmounts./init.sqlinto/docker-entrypoint-initdb.d/init-scripts/100-sudoky-init.sql.- This SQL runs automatically only when
supabase/volumes/db/data(PGDATA) is empty. - Restarting containers with existing PGDATA does not re-run init scripts.
Optional seed behavior:
supabase/seed.sqlis separated from schema init.- In
supabase/docker-compose.yml, the seed mount is commented by default:# - ./seed.sql:/docker-entrypoint-initdb.d/init-scripts/110-sudoky-seed.sql:Z
- Uncomment it for local/dev demos.
- Keep it commented for production environments.
Force re-init from scratch:
docker compose -f supabase/docker-compose.yml down
rm -rf supabase/volumes/db/data
docker compose -f supabase/docker-compose.yml uphttps://supabase.com/docs/guides/local-development/overview
Show help:
npx supabase --helpCommon local-dev commands:
npx supabase init
npx supabase start
npx supabase status
npx supabase stop
npx supabase db --help
npx supabase migration --help
npx supabase seed --help
npx supabase servicesUse Supabase CLI credentials in app .env.local:
cp .env.example .env.local
npx supabase start
npx supabase status -o envThen copy these values from the status -o env output into .env.local:
API_URL->NEXT_PUBLIC_SUPABASE_URLANON_KEY->NEXT_PUBLIC_SUPABASE_ANON_KEY
Example:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<ANON_KEY_FROM_SUPABASE_STATUS>Create and apply a new init migration with Supabase CLI:
# If `supabase` is not globally installed, use npx.
# `supabase migration new init` -> zsh: command not found: supabase
npx supabase migration new init
# Reset local DB and apply migrations from supabase/migrations
npx supabase db resetExpected output notes:
Created new migration at supabase/migrations/<timestamp>_init.sqlApplying migration <timestamp>_init.sql...NOTICE: extension "pgcrypto" already exists, skippingis normal.WARN: no files matched pattern: supabase/seed.sqlmeansdb.seed.sql_pathsinsupabase/config.tomlpoints to a file that does not exist at that path.- If your seed is at
supabase/seed.sql, set:[db.seed]sql_paths = ["./seed.sql"]
- If your seed is at
npx supabase login
npx supabase link --project-ref <project-id>
npx supabase db push
npx supabase migration list
npx supabase functions deploy <function-name> --project-ref <project-id>