Full app

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.

Next.js 16TypeScript 5Tailwind v4Prisma 7Better AuthPlateJS 52PostgresVercel BlobResend
portfolio.yoursite.com
Available for new projects

Hi, I'm Alex.

Designer & Developer

I craft modern, accessible web experiences with care for detail and craft.

View my workGet in touch
Selected workAll →
A
Design System·Sep 2025

Atlas — A modern design system

FigmaTailwindTypeScript
F
Mobile·Apr 2025

Fieldnote — A focus journal

SwiftUICoreMLLiquid Glass
new

command setup

1

no-code editing

100%

rich text

PlateJS

monthly fee

0$

license

MIT

deploy target

Vercel

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.sh walks non-developers through tooling check, database URL, admin credentials, install, schema push, and seed. No .env editing.
  • Deploy wizardbash deploy.sh handles gh 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

Interactive 3D-feel hero
Mouse-reactive particle constellation with parallax gradient orbs, 3D card tilt, animated typing headline, and a prefers-reduced-motion fallback that stays elegant.
PlateJS rich-text editor
Write project case studies and your bio with the same polished editor used in production SaaS — headings, lists, links, marks, callouts, code blocks, and image embeds.
Image uploads via Vercel Blob
Drag-and-drop cover images and gallery shots from the admin UI. Pasted URLs are accepted. Automatic content-type detection and size cap.
Secure single-admin login
Better Auth with a seeded admin user; no public sign-up. Session cookies, CSRF protection, password hashing, and role gating wired in.
SEO-ready structure
Dynamic per-page metadata, OpenGraph cards, sitemap.xml, robots.txt, Schema.org Person/Portfolio entity, and fast static rendering for marketing surfaces.
Filterable, taggable projects
Categories, tags, search, featured flag, sort order, optional gallery, optional external link, and rich-text case study body per project.
Contact inbox
The public contact form posts straight to your admin inbox. Mark read/unread, archive, search, and reply via mailto. Optional Resend forwarding to your real inbox.
Brandable in two minutes
Set your site name, tagline, accent color, default theme, and og image override from the admin Settings page. No code edits.
Audit log
Every admin action — create, update, delete, login — is recorded with timestamp and admin identity for accountability.
Postgres-backed with Prisma
Prisma 7 schema with typed queries, migrations included. Works with Neon, Vercel Postgres, Supabase, or any Postgres provider.
One-command deploy
`bash deploy.sh` runs `gh repo create`, pushes the code, links Vercel, pushes env vars, and triggers a production deploy. You own the repo and the Vercel project.
Light + dark mode
Full dark mode across every surface — public site and admin panel. Token-paired, respects system preference, persisted per visitor.

Tech stack & dependencies

What the app is built on and what you'll need to run it.

Other
  • Next.js16required
    App Router, static rendering for marketing pages, server actions for admin, and Vercel-optimized deploy
  • React19required
    Component runtime for both public site and admin panel
  • TypeScript5required
    Full type safety across schema, server actions, components, and admin forms
  • Tailwind CSSv4required
    Token system, palette, dark mode, and zero-runtime styling across public + admin surfaces
  • Prisma7required
    Schema, migrations, and typed query client for Postgres
  • PostgreSQLrequired
    Primary data store — works with Neon, Vercel Postgres, Supabase, or self-hosted
  • Better Authrequired
    Single-admin login, session cookies, CSRF protection, password hashing
  • PlateJS52required
    Rich-text editor for project case studies, bio, and other long-form content
  • Vercel Blobrequired
    Image upload storage for cover images, galleries, and headshots
  • Resendoptional
    Optional forwarding of public contact-form messages to your real inbox
  • lucide-reactrequired
    Icon set for admin nav, social link icons, and UI affordances
  • Hero parallax, project card hover, page transitions, and admin overlay motion

Full breakdown

Animated mouse-reactive hero
Particle constellation, parallax gradient orbs, 3D card tilt, animated typing headline, and reduced-motion fallback
About section
Bio with PlateJS rich text, headshot, location, availability flag, and social link strip
Skills grid
Grouped skills with proficiency levels, drag-to-reorder in admin, and responsive grid on the public site
Projects index
Filterable by category and tag, search, featured flag, sort order, and responsive cards with hover states
Project detail page
Cover image, gallery, PlateJS rich-text case study, external link, tags, and related-project rail
Contact form
Name, email, message, optional company, validation, success state, and optional Resend forwarding
Admin shell
Sidebar nav, Better Auth login, profile menu, dark/light toggle, and command-K palette for quick actions
Admin project CRUD
Add, edit, delete, reorder; categories + tags; cover image + gallery; PlateJS case-study editor; featured flag
Admin skills CRUD
Group by section; reorder; tag with proficiency level
Admin about-me editor
Rich-text bio, headshot upload, location, availability flag
Admin social links manager
Drag-to-reorder rows; icon-aware (GitHub, LinkedIn, X, Bluesky, Mastodon, custom)
Admin site settings
Site name, tagline, accent color, default theme, og image override
Admin contact inbox
Read/unread, archive, search, reply via mailto, optional Resend forwarding
Admin audit log
Every admin action recorded with timestamp, admin identity, and entity reference
Prisma 7 schema
Typed models for Project, Skill, Social, About, Setting, ContactMessage, AdminUser, and AuditLog
setup.sh wizard
Tooling check, Postgres URL prompt, admin credentials, install, schema push, seed, and dev server
deploy.sh wizard
GitHub repo create, Vercel auth, env push, and production deploy under your own accounts
SEO bundle
Dynamic metadata, OpenGraph, sitemap.xml, robots.txt, Schema.org structured data

How it works

01
Run the setup wizard
`bash setup.sh` checks Node/Bun, prompts for a Postgres URL and admin credentials, installs dependencies, pushes the Prisma schema, seeds sample content, and starts the dev server.
02
Sign in and edit
Open `/admin` and use the dashboard to add, edit, delete, or reorder projects, skills, socials, about-me copy, and site settings. Every change is live immediately.
03
Brand it
Use the Settings page in the admin to set your site name, tagline, accent color, default theme, and OG image. No code edits required.
04
Deploy under your own accounts
`bash deploy.sh` walks you through `gh repo create`, Vercel auth, env push, and a production deploy. You own the repo, the Vercel project, and the database.
05
Wire your domain
Point your domain at the Vercel project. The deploy script prints the exact CNAME records. SSL is automatic.
06
Optional: forward contact messages
Add your Resend API key in admin Settings and contact-form submissions will forward to your real inbox in addition to landing in the admin inbox.

Code preview

prisma/schema.prisma
// 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.

Need this customized?
We can adapt this for your stack, brand, or unique requirements. Most customizations ship in under a week.