Naresh-Khatri/3d-portfolio

Interactive 3D developer portfolio with a keyboard where every keycap is a skill. Built with Next.js, React, TypeScript, GSAP & Motion. Free to use!

TypeScript

1,315

363 commits

updated Oct 11, 2026

See the code

README

πŸš€ 3D Portfolio

A developer portfolio you can actually play with. Press keys on a 3D keyboard, watch other visitors' cursors fly by, and chat with whoever's online.

✨ Live Demo β†’ nareshkhatri.dev

GitHub stars Forks License: MIT Next.js 16

Deploy with Vercel

Portfolio Preview

Free to use! This portfolio is open source. If you use it, a credit/link back would be really appreciated πŸ™

✨ Features

  • Interactive 3D Keyboard β€” Programmatically generated Chibi keyboard where each keycap represents a skill, revealing titles and descriptions on hover/press. Try colors, logos, and layouts in the Chibi keycap customizer.
  • Live Multiplayer β€” See other visitors' cursors in realtime, who's online, and chat with them (details)
  • Buttery Animations β€” GSAP + Framer Motion powered scroll, hover, and reveal animations
  • Space Theme β€” Floating particles on a dark canvas for a cosmic vibe
  • Easter Eggs β€” Open DevTools and follow the clues 🐱
  • Light & Dark Mode β€” Full theme support with cheeky disclaimer toasts
  • Responsive β€” Works across all screen sizes
  • Contact Form β€” Email delivery via Resend
  • Analytics (optional) β€” Umami analytics integration

πŸ› οΈ Tech Stack

LayerTechnologies
FrameworkNext.js 16.2.2, React 19.2.4, TypeScript
StylingTailwind CSS, Shadcn UI, Aceternity UI
AnimationGSAP, Framer Motion
3D@chibi3d/runtime, Three.js, React Three Fiber
EmailResend
MiscLenis (smooth scroll), Zod, next-themes

πŸš€ Getting Started

Prerequisites

  • Node.js 20.9+ for Next.js 16; use a current LTS release with pnpm 11
  • pnpm 11.20.0

Installation

  1. Clone the repository:

    git clone https://github.com/Naresh-Khatri/3d-portfolio.git
    cd 3d-portfolio
    
  2. Install dependencies:

    pnpm install
    
  3. Set up environment variables:

    Copy .env.example to .env.local and fill in the values:

    cp .env.example .env.local
    
    VariableRequiredDescription
    RESEND_API_KEYYesAPI key from Resend for the contact form
    NEXT_PUBLIC_WS_URLNoWebSocket server URL for realtime features (cursors, chat, presence)
    UMAMI_DOMAINNoUmami analytics script URL
    UMAMI_SITE_IDNoUmami website ID
  4. Run the development server:

    pnpm dev
    
  5. Open http://localhost:3000 and see the magic ✨


Code checks

Run these before opening a pull request:

pnpm lint
pnpm typecheck

Next.js 16 no longer runs lint during builds. The ESLint CLI uses eslint.config.mjs. New React Compiler diagnostics for refs, immutability, effect state updates, and manual memoization report warnings while existing animation and realtime components are migrated. Hook ordering violations remain errors.

Blog frontmatter requires a title, summary, and publishedAt date in YYYY-MM-DD format. Optional fields are image, author, and a list of tags. Invalid frontmatter raises a content error; unknown blog slugs return a 404.

Files under public/assets can be replaced at the same URL and cache for one hour before revalidation. Next.js content-hashed static assets retain immutable caching.


🎨 Make It Your Own

All personal info is centralized in src/data/config.ts. Edit this single file to rebrand the portfolio:

const config = {
  title: "Your Name | Your Title",
  description: {
    long: "Your long description for SEO...",
    short: "Your short description...",
  },
  keywords: ["your", "keywords"],
  author: "Your Name",
  email: "[email protected]",
  site: "https://yoursite.com",

  // GitHub stars button in the header
  githubUsername: "your-github-username",
  githubRepo: "your-repo-name",

  social: {
    twitter: "https://x.com/you",
    linkedin: "https://linkedin.com/in/you",
    instagram: "https://instagram.com/you",
    facebook: "https://facebook.com/you",
    github: "https://github.com/you",
  },
};

Other files you'll want to customize:

FileWhat to change
src/data/projects.tsxYour projects, screenshots, descriptions, and tech stacks
src/data/constants.tsSkills list (name, description, icon) and work experience
public/assets/Your images, OG image, and project screenshots

⌨️ Customize the 3D keyboard

Try colors, logos, and layouts in the Chibi keycap customizer, then apply your choices to SKILLS in src/data/constants.ts:

  • keyboardColor: keycap color, such as "#ff9408".
  • keyboardIcon: copy an SVG URL from thesvg.org and paste it here. You can also use a local file under public/assets/keyboard/logos/.
  • label and shortDescription: text shown when interacting with a key.
  • shortcut: optional physical key code, such as "KeyQ". Keep shortcuts unique; defaults follow QWERTY letter order.

The demo accepts logo names too, but keyboardIcon needs an image URL or local asset path. Without keyboard overrides, keys use the skill's color and icon.

Keys follow the order of SKILLS. To change the default six columns, pass a second argument to createKeyboardScene in keyboard-scene.tsx. Rows adjust automatically to the skill count.


πŸ”Œ Realtime Features (Optional)

The portfolio supports optional realtime features powered by a separate backend API:

  • πŸ–±οΈ Live cursors β€” See other visitors' cursors in realtime
  • πŸ‘₯ Online presence β€” Shows who's currently on the site
  • πŸ’¬ Chat β€” Live chat between visitors
  • Zombie Survival with multiplayer and leaderboards on the live site.

These features activate automatically when the NEXT_PUBLIC_WS_URL environment variable is set. Without it, the portfolio works perfectly fine as a static site β€” no realtime features, no backend dependency.

[!NOTE] The backend API is not open source. This is intentional! Too many people have cloned the portfolio and claimed they built it from scratch. The realtime server stays private to keep the live experience unique and make it stand out.


πŸš€ Deployment

Deploy with Vercel

This site is deployed on Vercel. To deploy your own:

  1. Push your code to a GitHub repository
  2. Connect the repository to Vercel
  3. Add your environment variables in the Vercel dashboard
  4. Vercel handles the rest β€” automatic deployments on every push

🀝 Contributing

If you'd like to contribute or suggest improvements, feel free to open an issue or submit a pull request. All contributions are welcome!


πŸ“„ License

This project is open source and available under the MIT License.

If you use this portfolio, a credit or link back to the original repo would be much appreciated ❀️

Note on analytics: a deployed copy reports its own hostname once per browser (nothing else β€” no visitor, page, or referrer data) so I can see where the template gets used.

3d
animation
developer-portfolio
framer-motion
gsap
interactive
motion
nextjs
personal-website
portfolio
portfolio-template
portfolio-website
react
shadcn
spline
tailwindcss
threejs-alternative
typescript

Naresh-Khatri/3d-portfolio

Interactive 3D developer portfolio with a keyboard where every keycap is a skill. Built with Next.js, React, TypeScript, GSAP & Motion. Free to use!

TypeScript

1,315

363 commits

updated Oct 11, 2026

See the code

README

πŸš€ 3D Portfolio

A developer portfolio you can actually play with. Press keys on a 3D keyboard, watch other visitors' cursors fly by, and chat with whoever's online.

✨ Live Demo β†’ nareshkhatri.dev

GitHub stars Forks License: MIT Next.js 16

Deploy with Vercel

Portfolio Preview

Free to use! This portfolio is open source. If you use it, a credit/link back would be really appreciated πŸ™

✨ Features

  • Interactive 3D Keyboard β€” Programmatically generated Chibi keyboard where each keycap represents a skill, revealing titles and descriptions on hover/press. Try colors, logos, and layouts in the Chibi keycap customizer.
  • Live Multiplayer β€” See other visitors' cursors in realtime, who's online, and chat with them (details)
  • Buttery Animations β€” GSAP + Framer Motion powered scroll, hover, and reveal animations
  • Space Theme β€” Floating particles on a dark canvas for a cosmic vibe
  • Easter Eggs β€” Open DevTools and follow the clues 🐱
  • Light & Dark Mode β€” Full theme support with cheeky disclaimer toasts
  • Responsive β€” Works across all screen sizes
  • Contact Form β€” Email delivery via Resend
  • Analytics (optional) β€” Umami analytics integration

πŸ› οΈ Tech Stack

LayerTechnologies
FrameworkNext.js 16.2.2, React 19.2.4, TypeScript
StylingTailwind CSS, Shadcn UI, Aceternity UI
AnimationGSAP, Framer Motion
3D@chibi3d/runtime, Three.js, React Three Fiber
EmailResend
MiscLenis (smooth scroll), Zod, next-themes

πŸš€ Getting Started

Prerequisites

  • Node.js 20.9+ for Next.js 16; use a current LTS release with pnpm 11
  • pnpm 11.20.0

Installation

  1. Clone the repository:

    git clone https://github.com/Naresh-Khatri/3d-portfolio.git
    cd 3d-portfolio
    
  2. Install dependencies:

    pnpm install
    
  3. Set up environment variables:

    Copy .env.example to .env.local and fill in the values:

    cp .env.example .env.local
    
    VariableRequiredDescription
    RESEND_API_KEYYesAPI key from Resend for the contact form
    NEXT_PUBLIC_WS_URLNoWebSocket server URL for realtime features (cursors, chat, presence)
    UMAMI_DOMAINNoUmami analytics script URL
    UMAMI_SITE_IDNoUmami website ID
  4. Run the development server:

    pnpm dev
    
  5. Open http://localhost:3000 and see the magic ✨


Code checks

Run these before opening a pull request:

pnpm lint
pnpm typecheck

Next.js 16 no longer runs lint during builds. The ESLint CLI uses eslint.config.mjs. New React Compiler diagnostics for refs, immutability, effect state updates, and manual memoization report warnings while existing animation and realtime components are migrated. Hook ordering violations remain errors.

Blog frontmatter requires a title, summary, and publishedAt date in YYYY-MM-DD format. Optional fields are image, author, and a list of tags. Invalid frontmatter raises a content error; unknown blog slugs return a 404.

Files under public/assets can be replaced at the same URL and cache for one hour before revalidation. Next.js content-hashed static assets retain immutable caching.


🎨 Make It Your Own

All personal info is centralized in src/data/config.ts. Edit this single file to rebrand the portfolio:

const config = {
  title: "Your Name | Your Title",
  description: {
    long: "Your long description for SEO...",
    short: "Your short description...",
  },
  keywords: ["your", "keywords"],
  author: "Your Name",
  email: "[email protected]",
  site: "https://yoursite.com",

  // GitHub stars button in the header
  githubUsername: "your-github-username",
  githubRepo: "your-repo-name",

  social: {
    twitter: "https://x.com/you",
    linkedin: "https://linkedin.com/in/you",
    instagram: "https://instagram.com/you",
    facebook: "https://facebook.com/you",
    github: "https://github.com/you",
  },
};

Other files you'll want to customize:

FileWhat to change
src/data/projects.tsxYour projects, screenshots, descriptions, and tech stacks
src/data/constants.tsSkills list (name, description, icon) and work experience
public/assets/Your images, OG image, and project screenshots

⌨️ Customize the 3D keyboard

Try colors, logos, and layouts in the Chibi keycap customizer, then apply your choices to SKILLS in src/data/constants.ts:

  • keyboardColor: keycap color, such as "#ff9408".
  • keyboardIcon: copy an SVG URL from thesvg.org and paste it here. You can also use a local file under public/assets/keyboard/logos/.
  • label and shortDescription: text shown when interacting with a key.
  • shortcut: optional physical key code, such as "KeyQ". Keep shortcuts unique; defaults follow QWERTY letter order.

The demo accepts logo names too, but keyboardIcon needs an image URL or local asset path. Without keyboard overrides, keys use the skill's color and icon.

Keys follow the order of SKILLS. To change the default six columns, pass a second argument to createKeyboardScene in keyboard-scene.tsx. Rows adjust automatically to the skill count.


πŸ”Œ Realtime Features (Optional)

The portfolio supports optional realtime features powered by a separate backend API:

  • πŸ–±οΈ Live cursors β€” See other visitors' cursors in realtime
  • πŸ‘₯ Online presence β€” Shows who's currently on the site
  • πŸ’¬ Chat β€” Live chat between visitors
  • Zombie Survival with multiplayer and leaderboards on the live site.

These features activate automatically when the NEXT_PUBLIC_WS_URL environment variable is set. Without it, the portfolio works perfectly fine as a static site β€” no realtime features, no backend dependency.

[!NOTE] The backend API is not open source. This is intentional! Too many people have cloned the portfolio and claimed they built it from scratch. The realtime server stays private to keep the live experience unique and make it stand out.


πŸš€ Deployment

Deploy with Vercel

This site is deployed on Vercel. To deploy your own:

  1. Push your code to a GitHub repository
  2. Connect the repository to Vercel
  3. Add your environment variables in the Vercel dashboard
  4. Vercel handles the rest β€” automatic deployments on every push

🀝 Contributing

If you'd like to contribute or suggest improvements, feel free to open an issue or submit a pull request. All contributions are welcome!


πŸ“„ License

This project is open source and available under the MIT License.

If you use this portfolio, a credit or link back to the original repo would be much appreciated ❀️

Note on analytics: a deployed copy reports its own hostname once per browser (nothing else β€” no visitor, page, or referrer data) so I can see where the template gets used.

3d
animation
developer-portfolio
framer-motion
gsap
interactive
motion
nextjs
personal-website
portfolio
portfolio-template
portfolio-website
react
shadcn
spline
tailwindcss
threejs-alternative
typescript

Significant stargazers

CanisMinor

892 followers Β· starred Jan 2025

Elliot Chen

285 followers Β· starred Jul 2025

Jinho

80 followers Β· starred Jul 2025

Thanh Minh

16 followers Β· starred Jan 2026