Skip to content

Repository files navigation

Portfolio Template

A config-driven developer portfolio. Edit one file, get your own site — no component code required to personalize it.

Live Demo

Why this one

Most portfolio templates make you hunt through five files to change your name. This one doesn't — everything content-wise lives in src/config/site.js: your name, bio, projects, skills, links, and even the accent color. Swap that file, keep the components untouched.

No image assets are required to get a working site — projects without an image field render a generated gradient block with their initials instead, and the avatar works the same way. See "Images" below for the full fallback chain, including automatic GitHub repo preview cards.

Also included: a light/dark theme toggle (persists across visits, respects system preference on first load), glassmorphism on the nav bar and expanded project panels, an animated liquid-blob background derived from your accent color, and scroll-reveal animations on every section — all of it respects prefers-reduced-motion.

Quick Start

npm install
npm run dev

Then open src/config/site.js and replace the example content with yours.

Build for Production

npm run build

Deploys as a static site — Vercel, Netlify, GitHub Pages, Cloudflare Pages, all work with zero extra config.

Customizing

Content

Everything in src/config/site.js:

export const site = {
  name: "Your Name",
  role: "Your Title",
  tagline: "One line about what you do.",
  bio: "A few sentences for the About section.",
  accentColor: "79 70 229", // "R G B", no commas
  email: "you@example.com",
  links: [{ label: "GitHub", url: "https://github.com/you" }],
  skills: ["TypeScript", "React", "..."],
  projects: [
    {
      title: "Project Name",
      role: "Your role on it",
      year: "2025",
      description: "What it does and what you built.",
      tags: ["Node.js", "PostgreSQL"],
      url: "https://...",
      image: "",  // local path or full URL, see "Images" below
      repo: "",   // or "yourname/project-repo" for an automatic GitHub preview
    },
  ],
};

Color

Change accentColor — one value, reskins the whole site (buttons, hover states, the availability dot, project placeholder gradients). It's an RGB triplet so it can plug into Tailwind's alpha-value opacity syntax.

accentColor: "79 70 229",   // indigo (default)
accentColor: "16 130 92",   // green
accentColor: "190 60 40",   // rust
accentColor: "190 24 93",   // pink

The liquid background blobs, avatar/project placeholder gradients, and hover states all derive from this one value — nothing else to touch.

Avatar

Set avatar in the config to an image path or URL. Leave it null for a generated initials avatar (same gradient logic as the project placeholders, so it always matches your accent color).

Images

Each project's picture comes from a three-tier fallback, first match wins. Set image/repo to "" (the default) to skip a tier — no need to comment anything out:

  1. image — a local path (/assets/projects/name.png) or a full image URL (https://...), both work exactly the same way.
  2. repo — a GitHub repo in "owner/name" form. Pulls that repo's social-preview card straight from GitHub (opengraph.githubassets.com) with no image file, API key, or auth needed. If the repo doesn't exist or the image fails to load, it falls through to tier 3 automatically.
  3. Both empty — a generated gradient block using the project title's initials, tinted from your accentColor.

Avatars follow the same idea minus the repo tier: set avatar to a local path, a full URL, or leave it "" for a generated initials avatar. See public/assets/README.md for folder conventions and recommended image sizes.

Theme

The toggle in the nav switches data-theme on <html> between light and dark, persisted to localStorage under the key portfolio-theme. A small inline script in index.html sets it before first paint so there's no flash of the wrong theme on load. To change the dark-mode palette, edit the [data-theme="dark"] block in src/index.css.

Layout

The "numbered index" project list (src/components/ProjectRow.jsx) is the signature layout choice — click a row to expand it. If you'd rather have a card grid, that's the one component to rewrite; everything else reads from the same site.projects array regardless of how you render it.

Contact Dialog

"Get in touch" (nav) and "Send a message" (footer) both open a glass modal (src/components/ContactDialog.jsx) instead of jumping straight to your email client. Submitting it opens a mailto: link pre-filled with the visitor's name, email, and message — there's no backend collecting anything.

If you'd rather capture messages without relying on the visitor's email client being configured, swap the handleSubmit body in ContactDialog.jsx for a fetch POST to a form service — Formspree or EmailJS both work with a single call and have free tiers.

To add the dialog trigger anywhere else, wrap any label in it:

<ContactDialog className="your-classes-here">Say hello</ContactDialog>

Project Structure

public/
  assets/
    avatar/               your profile photo goes here
    projects/               your project screenshots go here
src/
  config/
    site.js              ← edit this
  components/
    Nav.jsx
    Hero.jsx
    ProjectsIndex.jsx      renders the list
    ProjectRow.jsx          single expandable row
    ProjectPlaceholder.jsx  image → GitHub repo preview → gradient fallback chain
    Avatar.jsx               generated fallback avatar (or your image)
    ThemeToggle.jsx           light/dark switch
    ContactDialog.jsx         glass contact modal (mailto-based)
    LiquidBackground.jsx     animated blob background
    Reveal.jsx                scroll-reveal wrapper
    About.jsx
    Footer.jsx
  hooks/
    useTheme.js            theme state + persistence
  utils/
    placeholder.js         shared initials/hue helpers
  App.jsx                 applies accentColor as a CSS variable on load

Tech Stack

Vite + React + Tailwind. No backend, no database, no build step beyond vite build.

License

MIT — use it, fork it, ship it as your own. Credit is appreciated but not required.

About

forkable, editorial-style portfolio template — one config file (site.js), Vite + React + Tailwind, no CMS or backend required.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages