Modern Portfolio
A polished, brandable portfolio site with a built-in admin panel — no code edits needed. One-command setup, one-command deploy, lifetime updates.
Hi, I'm Alex.
Designer & Developer
I craft modern, accessible web experiences with care for detail and craft.
Atlas — A modern design system
Fieldnote — A focus journal
command setup
no-code editing
rich text
monthly fee
license
deploy target
What you get
A complete, production-ready personal-portfolio kit that ships under your own domain, on your own accounts, with no recurring SaaS fee:
- Public site — animated mouse-reactive hero with particle constellation and parallax gradient orbs, About section, Skills grid, filterable Projects index, Project detail with gallery, and a contact form that posts straight to your admin inbox. Light + dark mode. Fully responsive from 320px to 4K.
- Admin panel at `/admin` — secure single-admin login (Better Auth), PlateJS rich-text editor for case studies and bio, Vercel Blob image uploads with drag-drop, full CRUD for projects (with categories, tags, gallery, featured flag, sort order, optional external link), skills, social links, about-me copy, theme/site settings, and a contact-message inbox with read/unread + reply-to.
- SEO-ready — dynamic metadata, OpenGraph cards, sitemap.xml, robots.txt, Schema.org structured data for the Person/Portfolio entity, fast static rendering for marketing surfaces.
- Setup wizard — a single
bash setup.shwalks non-developers through tooling check, database URL, admin credentials, install, schema push, and seed. No.envediting. - Deploy wizard —
bash deploy.shhandlesgh repo create, Vercel auth, env push, and a production deploy. You own the repo and the Vercel project.
Why this exists
Most portfolio templates are static. You change a project by editing TypeScript, committing, and waiting for a deploy. This one ships with an admin panel because changing your portfolio shouldn't require a git workflow — it should take 30 seconds in a browser.
What's in the admin panel
- Projects — Add, edit, delete, reorder; categories + tags; featured flag; cover image + gallery; external link; PlateJS case-study editor.
- Skills — Group by section; reorder; tag with proficiency level.
- About me — Rich-text bio, headshot, location, availability flag.
- Social links — Drag-to-reorder; icon-aware (GitHub, LinkedIn, X, Bluesky, Mastodon, custom).
- Site settings — Site name, tagline, dominant accent color, dark/light default, og image override.
- Contact inbox — Messages from the public contact form land here. Mark read/unread, archive, reply via mailto.
- Audit log — Every admin action is recorded for accountability.
Stack
Next.js 16 (App Router), TypeScript 5, Tailwind v4, Prisma 7, Better Auth, PlateJS 52, Postgres (Neon-compatible), Vercel Blob, Resend (optional for contact email forwarding).
What you don't get
No CMS subscription. No vendor lock-in. No monthly fee. You own the code, the data, the deploy.
Highlights
Tech stack & dependencies
What the app is built on and what you'll need to run it.
- App Router, static rendering for marketing pages, server actions for admin, and Vercel-optimized deploy
- Component runtime for both public site and admin panel
- Full type safety across schema, server actions, components, and admin forms
- Token system, palette, dark mode, and zero-runtime styling across public + admin surfaces
- Schema, migrations, and typed query client for Postgres
- PostgreSQLrequiredPrimary data store — works with Neon, Vercel Postgres, Supabase, or self-hosted
- Better AuthrequiredSingle-admin login, session cookies, CSRF protection, password hashing
- Rich-text editor for project case studies, bio, and other long-form content
- Vercel BlobrequiredImage upload storage for cover images, galleries, and headshots
- ResendoptionalOptional forwarding of public contact-form messages to your real inbox
- lucide-reactrequiredIcon set for admin nav, social link icons, and UI affordances
- Framer MotionrequiredHero parallax, project card hover, page transitions, and admin overlay motion
Full breakdown
How it works
Code preview
// Admin user / session models are provided by Better Auth.
model Project {
id String @id @default(cuid())
slug String @unique
title String
summary String
content String?
category String
date DateTime
coverImage String?
link String?
gallery Json?
tags String[]
featured Boolean @default(false)
published Boolean @default(true)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([published, sortOrder])
@@index([category])
}
model Skill {
id String @id @default(cuid())
name String
category String
level Int @default(3)
sortOrder Int @default(0)
}
model SocialLink {
id String @id @default(cuid())
platform String
url String
sortOrder Int @default(0)
}
model SiteSettings {
id String @id @default("default")
siteName String @default("Portfolio")
tagline String @default("Maker of things")
accentColor String @default("#7c3aed")
defaultTheme String @default("system")
ogImage String?
aboutContent String?
headshot String?
location String?
resendApiKey String?
}
model ContactMessage {
id String @id @default(cuid())
name String
email String
message String
read Boolean @default(false)
archived Boolean @default(false)
createdAt DateTime @default(now())
}FAQ
No. The setup wizard handles install, database, and seeding. After that, everything you'd want to change lives in the admin panel — no .env editing, no TypeScript edits, no git commits required.