Paper demo: live-style crypto overview, email-based sign-up, and a simple dashboard.
Not a broker or financial advice.
cp .env.example .env # Windows: copy .env.example .env
# Edit .env (Neon URLs, AUTH_*, Resend, etc.)
npm install
npx prisma generate
npm run db:migrate
npm run devOpen http://localhost:3000.
- Markets — Reads a cached snapshot from Postgres; CoinGecko refreshes that snapshot on a schedule (cron on Vercel or
npm run markets:refreshlocally). - Auth — Register with email; server emails a generated password. Sign in with NextAuth (credentials + JWT).
- Dashboard — Protected route for signed-in users.
- Next.js 16 — App Router, webpack (
--webpackon dev/build) - React 19
- TypeScript
- Tailwind CSS 4
- Geist —
next/font - Recharts
- PostgreSQL — hosted on Neon
- Prisma 6 —
DATABASE_URL(pooler) +DIRECT_URL(migrations) - NextAuth.js v5 (Auth.js) — Credentials, JWT, @auth/prisma-adapter
- bcryptjs
- Resend — registration emails
- CoinGecko API — optional API key; data lands in
market_snapshots
- tsx + dotenv — scripts
- patch-package — see
patches/next+*.patch - Vercel — hosting + cron (
vercel.json→/api/cron/refresh-markets)
Copy .env.example → .env.
| Variable | Purpose |
|---|---|
DATABASE_URL |
Neon pooled URL |
DIRECT_URL |
Neon direct URL (Prisma migrations) |
AUTH_SECRET |
NextAuth secret |
AUTH_URL |
Public app URL (e.g. http://localhost:3000 or your Vercel URL) |
RESEND_API_KEY |
Resend API key |
EMAIL_FROM |
Sender, e.g. Coinflow <onboarding@resend.dev> |
CRON_SECRET |
On Vercel, cron requests include Authorization: Bearer <CRON_SECRET> |
COINGECKO_API_KEY |
Optional |
| Script | Description |
|---|---|
npm run dev |
Dev server (webpack) |
npm run build |
Local production build |
npm run vercel-build |
Migrations + generate + build (matches Vercel) |
npm run db:migrate |
Prisma migrate (dev) |
npm run markets:refresh |
Pull CoinGecko → update DB snapshot |
- Import the repo and set the same env vars in the project dashboard.
- Set
AUTH_URLto your production URL. - After the first deploy, run a market refresh once if the UI is empty (wait for cron or call the protected cron route).
Learning / demo project only. Market data may be outdated. Not a trading product.