Loading repository data…
Loading repository data…
nixrajput / repository
This repository contains the source code for a portfolio website built using Next.js, TypeScript, Sass, Tailwind, and Aceternity UI.
Personal portfolio website for Nikhil Rajput, rebuilt from scratch on the modern Next.js 16 stack with a database-driven content layer, GitHub OAuth admin panel, and full CI/test suite.
[][repo]
[
][repo]
[
][repo]
[
][repo]
[][repo]
[
][issues]
[
][pulls]
[
][license]
An immersive, cursor-reactive hero over a page-wide gradient background, with a first-class light and dark theme.
| Dark theme | Light theme |
|---|---|
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| UI library | React 19 |
| Language | TypeScript |
| Styling | Tailwind CSS v4, Geist font |
| Animation | Framer Motion |
| Icons | Lucide React |
| Database | PostgreSQL via postgres-js |
| ORM | Drizzle ORM |
| Auth | Auth.js v5 — GitHub OAuth |
| File storage | Vercel Blob |
| Resend | |
| Analytics | Vercel Analytics + Google Analytics |
| Package manager | Bun |
| Unit tests | Vitest + Testing Library |
| E2E tests | Playwright |
| Deployment | Vercel |
bun run db:seed. The admin panel allows live CRUD editing. The profile drives the hero (name, editable role marquee, "Currently" tagline, avatar) and the About section.GITHUB_TOKEN. Only repos listed in the database are enriched.AUTH_GITHUB_ID / AUTH_GITHUB_SECRET). Access is restricted to the GitHub login set in ADMIN_GITHUB_LOGIN (default: nixrajput). The panel exposes CRUD tabs for all content types plus the testimonial moderation queue.robots.txt are generated from the database profile row and site config.git clone https://github.com/nixrajput/portfolio-nextjs.git
cd portfolio-nextjs
bun install
Copy .env.example to .env.local and fill in the values:
cp .env.example .env.local
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string, e.g. postgres://user:pass@localhost:5432/portfolio |
AUTH_SECRET | Yes | Random secret for Auth.js session encryption (openssl rand -base64 32) |
AUTH_GITHUB_ID | Yes | GitHub OAuth App client ID |
AUTH_GITHUB_SECRET | Yes | GitHub OAuth App client secret |
ADMIN_GITHUB_LOGIN | Yes | GitHub username allowed to access the admin panel (e.g. nixrajput) |
GITHUB_TOKEN | Recommended | GitHub personal access token for project metadata fetching (higher rate limits) |
BLOB_READ_WRITE_TOKEN | Yes (prod) | Vercel Blob token for image uploads (avatar, skill icons, testimonial avatars) |
RESEND_API_KEY | Yes (prod) | Resend API key for admin notification emails |
RESEND_FROM_EMAIL | Yes (prod) | From address for emails, e.g. Portfolio <noreply@nixrajput.com> (verified domain) |
CONTACT_EMAIL | Yes (prod) | Email address to receive testimonial submission notifications |
REVALIDATE_SECRET | Yes (prod) | Secret for the /api/revalidate on-demand revalidation endpoint |
NEXT_PUBLIC_SITE_URL | Yes | Canonical site URL, e.g. https://nixrajput.com |
NEXT_PUBLIC_GTAG_ID | Optional | Google Analytics measurement ID (e.g. G-XXXXXXXXXX) |
NEXT_PUBLIC_GOOGLE_VERIFICATION_TOKEN | Optional | Google Search Console site verification token |
The resume link is stored in the database (
profile.resumeUrl) and managed from the admin panel — not via an environment variable.
Run migrations to create the schema, then seed initial data:
bunx drizzle-kit migrate
bun run db:seed
Enable the pre-push lint + format gate once per clone:
git config core.hooksPath .githooks
This runs bun run lint and bun run format:check before every push. Bypass in an emergency with git push --no-verify.
bun run dev
The site is available at http://localhost:4000.
| Command | Description |
|---|---|
bun run dev | Start dev server (Turbopack, port 4000) |
bun run build | Production build (Turbopack) |
bun run start | Start production server |
bun run lint | Run ESLint |
bun run lint:fix | Run ESLint with auto-fix |
bun run format | Format source files with Prettier |
bun run format:check | Check formatting without writing |
bun run typecheck | Run tsc --noEmit |
bun run test | Run Vitest unit tests |
bun run test:watch | Run Vitest in watch mode |
bun run test:e2e | Run Playwright end-to-end tests |
bun run db:generate | Generate a new Drizzle migration |
bun run db:migrate | Apply pending migrations |
bun run db:push | Push schema changes directly (dev only) |
bun run db:studio | Open Drizzle Studio |
bun run db:seed | Seed the database with initial data |
The admin panel is at /admin and requires authentication via GitHub OAuth.
ADMIN_GITHUB_LOGIN (e.g. nixrajput) can sign in.Image uploads (avatar, skill icons) require BLOB_READ_WRITE_TOKEN to be set.
The site is deployed on Vercel. The main branch deploys automatically.
DATABASE_URL to its pooled connection string.DATABASE_URL: DATABASE_URL=<prod> bun run db:seed. The seed is guarded (seed-if-empty), so it inserts the initial content only when the database is empty and never overwrites later edits.master — Vercel runs the vercel-build script, which applies pending migrations and then builds. It does not seed; data seeding is the one-time manual step above