A modern, performant personal portfolio website showcasing my work, experience, and blog posts. Built with Next.js 15, React 19, TypeScript, and Tailwind CSS 4.
🔗 Live Demo: https://shakirul.dev/
- Unique Horizontal Scroll Design - Desktop view with smooth horizontal scrolling, vertical on mobile
- MDX Blog - Write blog posts with MDX for rich, interactive content
- Type-Safe - Full TypeScript implementation with strict type checking
- SEO Optimized - Built-in sitemap, robots.txt, and structured data
- Performance First - Optimized for Core Web Vitals with Vercel Analytics
- Code Quality - Enforced with Ultracite (Biome) for formatting and linting
- Accessibility - WCAG compliant with semantic HTML and ARIA attributes
- Modern Stack - Next.js 15 with App Router, React 19, and Tailwind CSS 4
- Responsive Design - Mobile-first approach with adaptive layouts
- Syntax Highlighting - Beautiful code blocks with rehype-highlight
- Next.js 15.4.6 - React framework with App Router
- React 19.1.0 - UI library
- TypeScript 5 - Type safety
- Tailwind CSS 4 - Utility-first styling
- MDX - Markdown with JSX support
- next-mdx-remote - Load MDX content
- gray-matter - Parse frontmatter
- reading-time - Estimate reading time
- rehype-highlight - Syntax highlighting
- @phosphor-icons/react - Icon library
- @tailwindcss/typography - Prose styling
- Ultracite - Fast code formatter and linter
- Vercel Analytics - Performance monitoring
- Bun - Fast package manager and runtime
- Bun 1.0+ (recommended) or Node.js 20+
- Git
-
Clone the repository
git clone https://github.com/KhanShaheb34/portfolio.git cd portfolio -
Install dependencies
# Using bun (recommended) bun install # Or using npm npm install # Or using yarn yarn install # Or using pnpm pnpm install
-
Run the development server
bun dev # Or using npm npm run dev # Or using yarn/pnpm yarn dev
-
Open your browser
Navigate to http://localhost:3000
.
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── about/ # About page
│ │ ├── posts/ # Blog posts
│ │ │ ├── [slug]/ # Dynamic blog post pages (MDX)
│ │ │ └── page.tsx # Blog listing
│ │ ├── projects/ # Projects showcase
│ │ │ ├── [slug]/ # Dynamic project pages
│ │ │ └── page.tsx # Projects listing
│ │ ├── work/ # Work experience
│ │ │ ├── [slug]/ # Dynamic work experience pages
│ │ │ └── page.tsx # Work listing
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Home page
│ │ ├── globals.css # Global styles
│ │ ├── manifest.ts # PWA manifest
│ │ ├── sitemap.ts # Dynamic sitemap
│ │ ├── robots.ts # Robots.txt
│ │ └── opengraph-image.tsx # OG image generator
│ │
│ ├── components/ # React components
│ │ ├── BlogLayout.tsx # Blog post layout
│ │ ├── CodeHighlight.tsx # Code syntax highlighting
│ │ ├── Column.tsx # Layout column component
│ │ ├── ExperienceCard.tsx # Work experience card
│ │ ├── InterestCard.tsx # Interest/hobby card
│ │ ├── PostCard.tsx # Blog post card
│ │ ├── ProjectCard.tsx # Project card
│ │ ├── ScrollArrows.tsx # Navigation arrows
│ │ ├── Section.tsx # Content section
│ │ └── SocialLink.tsx # Social media link
│ │
│ ├── data/ # JSON data files
│ │ ├── experiences.json # Work experience data
│ │ ├── portfolio.json # Personal info, intro, interests
│ │ └── projects.json # Project showcase data
│ │
│ ├── hooks/ # Custom React hooks
│ │ └── useColumnVisibility.ts
│ │
│ ├── lib/ # Utility functions
│ │ ├── blog.ts # Blog post utilities
│ │ └── projects.ts # Project utilities
│ │
│ └── mdx-components.tsx # Custom MDX components
│
├── public/ # Static assets
│ └── icons/ # Favicon and app icons
│
├── biome.jsonc # Biome (Ultracite) configuration
├── next.config.ts # Next.js configuration
├── tailwind.config.ts # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Dependencies and scripts
Update your personal information in the JSON files located in src/data/:
portfolio.json- Intro, social links, interests, academic info, hobbiesprojects.json- Project showcase with descriptions, tech stack, and linksexperiences.json- Work experience with responsibilities and achievements
Create new blog posts in src/app/posts/[slug]/ directory:
// src/app/posts/my-new-post/page.mdx
import BlogLayout from '@/components/BlogLayout';
export const metadata = {
title: 'My New Post',
description: 'A brief description of my post',
date: '2025-10-17',
author: 'Your Name',
};
# My New Post
Your content here...
export default ({ children }) => (
<BlogLayout metadata={metadata}>{children}</BlogLayout>
);Customize colors and fonts in src/app/globals.css:
:root {
--background: #ffffff;
--foreground: #171717;
--muted: #737373;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--muted: #a3a3a3;
}
}Create a .env.local file for environment-specific configuration:
# Add any API keys or environment-specific variables here
# Example:
# NEXT_PUBLIC_ANALYTICS_ID=your_analytics_id# Start development server (with Turbopack)
bun dev
# Build for production
bun run build
# Start production server
bun start
# Run linter
bun run lint
# Format and fix code with Ultracite
bunx ultracite format
# Check for issues without fixing
bunx ultracite lintThis project uses Ultracite (powered by Biome) for code formatting and linting. It enforces:
- Strict type safety
- Accessibility standards (WCAG compliance)
- React and TypeScript best practices
- Consistent code style
- Create a new directory in
src/app/ - Add a
page.tsxfile - Export your page component
// src/app/contact/page.tsx
export default function ContactPage() {
return (
<main>
<h1>Contact Me</h1>
</main>
);
}bun run buildThis creates an optimized production build in the .next directory.
- Push your code to GitHub
- Import your repository to Vercel
- Configure environment variables (if needed)
- Deploy!
This is a standard Next.js application and can be deployed to:
- Netlify - Use the
next exportor Next.js Runtime - AWS Amplify - Direct GitHub integration
- Docker - Use the included Dockerfile (if you add one)
- Self-hosted - Use
bun run buildandbun start
- Fork this repository
- Update personal data in
src/data/*.json - Modify colors in
src/app/globals.css - Replace blog posts in
src/app/posts/ - Update metadata in
src/app/layout.tsx - Update OG image in
src/app/opengraph-image.tsx - Deploy to your hosting provider
The design uses CSS custom properties for easy theming:
/* src/app/globals.css */
:root {
--background: #ffffff; /* Main background color */
--foreground: #171717; /* Main text color */
--muted: #737373; /* Muted text color */
}All components are modular and can be easily customized:
- Layout: Modify
Column.tsxandSection.tsx - Cards: Customize card components in
src/components/ - Navigation: Update
ScrollArrows.tsxfor different navigation
This project is licensed under the MIT License - see the LICENSE file for details.
Shakirul Hasan Khan
- Website: https://shakirul.dev
- GitHub: @KhanShaheb34
- LinkedIn: shakirulhasan
- Twitter: @_khanshaheb
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Give a ⭐️ if this project helped you or if you like the design!
If you have any questions or need help with customization:
- Open an issue
- LinkedIn: Message me
- Built with Next.js
- Styled with Tailwind CSS
- Icons by Phosphor Icons
- Code quality by Ultracite
- Hosted on Vercel
Made with ❤️ by Shakirul Hasan Khan