PortfolioSathi is a Next.js 14 portfolio generator that turns two inputs into a polished, animated developer portfolio:
- a GitHub username
- a LinkedIn PDF export
It uses only free public data sources and server-side parsing:
- GitHub Public REST API v3
pdf-parseon the server- no paid API keys
- no AI service calls
The app ships with three theme systems:
- Cosmic
- Minimal Pro
- Terminal
It is built for Vercel deployment and keeps the generated portfolio data in local storage so the preview survives navigation and refreshes.
- The user opens
/generate - The app validates the GitHub username in real time
- The user uploads a LinkedIn PDF
- The app fetches GitHub profile/repository data
- The app parses the PDF server-side into structured profile data
- The user edits the extracted fields
- The user selects a theme
- The final portfolio renders in
/preview
- Next.js 14 App Router
- TypeScript
- Tailwind CSS
- shadcn-style UI primitives
- Framer Motion
- Three.js
@react-three/fiber@react-three/drei- Zustand
pdf-parse- GitHub public REST API v3
app/
layout.tsx
page.tsx
generate/page.tsx
preview/page.tsx
api/github/route.ts
api/parse-linkedin/route.ts
components/
generator/
portfolio/
three/
ui/
lib/
types.ts
github.ts
parseLinkedin.ts
portfolioStore.ts
public/
fonts/
File: app/generate/page.tsx
- GitHub username field with live validation
- LinkedIn PDF drag-and-drop upload
- loading state while fetching/parsing
- error states for invalid GitHub usernames and failed PDF parsing
File: app/api/github/route.ts
Returns:
- profile name
- bio
- avatar URL
- location
- blog
- followers
- top repositories
- aggregated languages
File: app/api/parse-linkedin/route.ts
Parses the uploaded PDF on the server and extracts:
- full name
- headline / current role
- location
- work experience
- education
- skills
If parsing is incomplete, the user can still edit the form manually.
File: components/generator/EditableForm.tsx
The extracted data is editable before generation:
- name
- headline
- bio
- LinkedIn URL
- skills
- projects
- experience
- education
File: components/generator/ThemeSelector.tsx
Themes:
- Cosmic: dark space background, star field, wireframe globe
- Minimal Pro: editorial layout, soft neutral palette, floating geometry
- Terminal: GitHub-dark style, code-heavy green aesthetic, matrix motion
File: app/preview/page.tsx
The portfolio sections are:
- Hero
- About
- Skills
- Projects
- Experience
- Education
- Contact
Defined in lib/types.ts.
interface PortfolioData {
name: string;
avatar: string;
githubBio: string;
location: string;
githubUrl: string;
followers: number;
projects: {
name: string;
description: string;
stars: number;
language: string;
repoUrl: string;
liveUrl: string;
show: boolean;
}[];
headline: string;
linkedinUrl: string;
skills: string[];
experience: {
company: string;
role: string;
duration: string;
description: string;
}[];
education: {
institution: string;
degree: string;
year: string;
}[];
customBio: string;
email: string;
selectedTheme: "cosmic" | "minimal" | "terminal";
}Fetches GitHub profile and repository data from the public API.
Accepts a multipart PDF upload and returns parsed JSON.
Portfolio data is stored in Zustand and persisted in browser local storage.
This means:
- preview still works after navigation
- refresh does not wipe the generated portfolio
- the user can continue editing after returning to the app
npm install
npm run devOpen:
http://localhost:3000
npm run dev- start development servernpm run build- build production bundlenpm run start- run production servernpm run typecheck- run TypeScript strict checknpm run lint- run Next lint
This app has been checked with:
npm run typechecknpm run build
- Three.js components are client-only and loaded with dynamic imports.
- PDF parsing runs only on the server route.
- Framer Motion respects reduced-motion preferences through the shared motion wrapper.
- The app is responsive and should work on mobile and desktop.
This project is Vercel-ready.
Make sure the following remain true in production:
- Node 18+ or Node 20+
npm installruns successfully- the app can reach
api.github.com