Brackeys is the community web app for the Brackeys Discord. This repo is a single TanStack Start application that powers:
- the home / jam landing page
- the command center
- developer profiles
- the collab board
This README is the repo-level source of truth for local setup and day-to-day development. The old starter README is intentionally replaced because it no longer matched the codebase.
- TanStack Start + Vite
- React 19
- TanStack Router, Query, Store, and Devtools
- Tailwind CSS v4
- Biome
- Drizzle ORM + PostgreSQL
- Better Auth
- ORPC
- Storybook
/home / jam landing page/command-centercommand and macro docs/profilesign-in gate and profile entry/profile/:userIdpublic profile view and owner edit flow/collabcollab browse flow/collab/newcollab post creation/collab/:postIdcollab post detail/oauth/github/callbackGitHub account-link callback/oauth/itchio/callbackitch.io link callback/api/auth/*Better Auth endpoints/api/rpc/*ORPC endpoints
src/
components/
collab/
home/
layout/
profile/
ui/
db/
lib/
orpc/
routes/
drizzle/
.storybook/
Important files:
src/routes/__root.tsx: shell, background, command palette, layoutsrc/db/schema.ts: app schemasrc/lib/auth.ts: Better Auth provider configsrc/orpc/router/*: typed server proceduresdrizzle.config.ts: Drizzle config
- Bun
- PostgreSQL
- Discord OAuth app credentials
Optional but relevant depending on what you are working on:
- GitHub OAuth app credentials
- itch.io client ID
- Strapi instance for collab image uploads
- MinIO credentials for profile image uploads
- PostHog project API key
- Install dependencies.
bun install- Create local env vars.
Copy-Item .env.example .env.local- Fill in the required secrets in
.env.local.
Minimum required for most local work:
DATABASE_URLBETTER_AUTH_URLBETTER_AUTH_SECRETDISCORD_CLIENT_IDDISCORD_CLIENT_SECRETDISCORD_GUILD_ID
- Apply database schema.
Only the user should ever run bun run db:generate, bun run db:migrate, or
bun run db:push. Agents should update schema and migration files, but the
user remains the only operator for those commands.
For an existing migration flow:
bun run db:migrateFor fast local iteration against an empty local database:
bun run db:push- Start the dev server.
bun run devThe app runs on http://localhost:3000.
README only documents variables that are actually referenced in the repo today.
DATABASE_URL: Postgres connection stringBETTER_AUTH_URL: local app URL, usuallyhttp://localhost:3000BETTER_AUTH_SECRET: Better Auth secretDISCORD_CLIENT_ID: Discord OAuth client IDDISCORD_CLIENT_SECRET: Discord OAuth client secretDISCORD_GUILD_ID: guild used for member role/profile enrichment
GITHUB_CLIENT_ID: GitHub account linkingGITHUB_CLIENT_SECRET: GitHub account linkingVITE_ITCHIO_CLIENT_ID: itch.io linking flowVITE_STRAPI_URL: Strapi-backed uploads / demo contentMINIO_ENDPOINT: MinIO server URL, for examplehttps://your-minio-host.up.railway.appMINIO_PUBLIC_BASE_URL: public base URL used to render stored objectsMINIO_BUCKET: bucket name for uploaded profile project imagesMINIO_ACCESS_KEY: MinIO access keyMINIO_SECRET_KEY: MinIO secret key
VITE_APP_TITLE: client title overrideSERVER_URL: server-side absolute URL overrideVITE_POSTHOG_KEY: PostHog project API key — analytics, feature flags, error tracking (all off when unset)VITE_POSTHOG_HOST: PostHog ingestion host, for examplehttps://eu.i.posthog.com, or the reverse proxy path onceworkers/posthog-proxyis deployed. Inlined into the browser bundle at build time — changing it needs a rebuild, not just a restart.POSTHOG_PERSONAL_API_KEY: build-time, server-only — enables source-map upload so error stacks are un-minified. Never give this aVITE_prefix: it is a write credential and the prefix would inline it into the browser bundle. Absent means maps are simply not uploaded.POSTHOG_PROJECT_ID: build-time, pairs with the personal API keyPOSTHOG_API_HOST: build-time, optional — the PostHog API/UI host for source-map upload (https://eu.posthog.com). Distinct from the ingestion host below; do not set both to the same value.POSTHOG_KEY/POSTHOG_HOST: read by theservices/*workers for error reporting; they fall back to theVITE_-prefixed names so one Railway shared variable can cover everything
If you have access to the Railway project, you can pull environment variables directly from Railway instead of maintaining .env.local manually.
https://docs.railway.com/cli#installing-the-cli
npm i -g @railway/cli
# or MacOS
brew install railway
# or Linux/WSL
bash <(curl -fsSL cli.new)railway login
railway linkThe interactive prompt will ask you to select the workspace, project, environment, and service.
railway environment # list available environments
railway environment dev # switch to devUse the railway:* scripts to run any command with Railway-injected environment variables:
vp run railway:dev # dev server with Railway env vars
vp run railway:build # production build
vp run railway:db:migrate # run migrations against Railway database
vp run railway:db:studio # open Drizzle Studio against Railway databaseYou can also pass -s <service> and -e <environment> flags inline:
railway run -e staging -- vp dev --port 3000The standard bun run dev / vp run dev workflow with .env.local continues to work for developers who do not need Railway CLI.
bun run dev
bun run build
bun run preview
bun run start
bun run db:generate
bun run db:migrate
bun run db:push
bun run db:pull
bun run db:studio
bun run lint
bun run format
bun run check
bun run test
bun run storybook
bun run build-storybookbun run db:generate, bun run db:migrate, and bun run db:push are
user-only commands. Do not have agents execute them.
__APP_VERSION__ (footer, PostHog app_version, source-map release) is a Vite
define assembled at build time in vite.config.ts:
<package.json version>+<UTC build stamp>.<short sha>
0.0.0-alpha+20260906.0441.8ab5478
The stamp orders builds and the sha pins one. Railway exposes
RAILWAY_GIT_COMMIT_SHA, GitLab exposes CI_COMMIT_SHA, and a local build
falls back to git rev-parse. Nothing bumps package.json automatically;
change its version by hand when the release line moves:
npm version preminor --preid=beta --no-git-tag-version # → 0.1.0-beta.0
npm version minor --no-git-tag-version # → 0.1.0- Discord is the primary sign-in path.
- GitHub linking and GitHub contribution calendar rendering are implemented.
- itch.io linking exists and is token/client-ID based in the current implementation.
- Public profile links prefer linked provider URLs over manual URLs when available.
- OAuth-backed GitHub and itch.io links now render verified badges in the public profile UI.
src/routes/demo/*still contains scaffold/demo routes and should not be treated as product truth.
The schema currently spans:
authuserhammercollab- public
todos
Profile data still uses separate profile_projects and jam_participations tables. The unified typed-projects migration has not landed yet.
bun run checkruns Biome across the repo.bun run testuses Vitest.- First-party automated coverage appears limited at the moment, so UI and route changes still need manual verification.
- Prefer reading the code over assuming the starter framework defaults still apply.
- Treat Notion as the longer-lived cross-session source of truth for architecture, drift, and planning context.
- Keep Linear issue status aligned with what actually shipped in the repo.
- The repo still needs a fuller setup/runbook for external services and credential provisioning.
- Demo routes remain in-tree.
- The route tree currently has at least one existing TypeScript issue outside normal profile work (
src/routes/profile.$userId.tsx), so isolated validation is sometimes more useful than full repo typechecking.