Live Demo: https://hassancodes.in/
A clean, minimalist portfolio website featuring smooth animations and a professional design. Built with React, TypeScript, and Tailwind CSS.
- π¨ Minimalist Design - Clean lines, ample whitespace, and restrained color palette
- π± Fully Responsive - Optimized for all screen sizes
- β¨ Subtle Animations - Smooth scroll-triggered animations
- π±οΈ Hover Effects - Interactive elements with clean transitions
- πΌ Project Showcase - Card-based layout with tech tags
- π― Skills Display - Clean pill-based tech stack showcase
- π§ Contact Form - Integrated with Formspree for email submissions
- π Social Links - GitHub, LinkedIn, LeetCode, X (Twitter), and Email
- π Resume Link - Direct access to downloadable resume
- π΅ Easter Egg - Hidden UFO music feature
- π Back to Top Button - Smooth scroll navigation
- Vite - Lightning-fast build tool and dev server
- React 18 - Modern UI library with hooks
- TypeScript - Type-safe development
- Tailwind CSS - Utility-first styling
- shadcn/ui - Beautiful, accessible component library
- Radix UI - Unstyled, accessible primitives
- Lucide React - Clean, consistent icons
- React Hook Form - Performant form state management
- Zod - TypeScript-first schema validation
- Formspree - Backend form handling
- React Router - Client-side routing
- TanStack Query - Data fetching and caching
- Vercel Analytics - Performance monitoring
- Node.js 18+ or Bun
- npm, yarn, or bun package manager
- Clone the repository:
git clone https://github.com/hassarch/starlight-portfolio.git
cd starlight-portfolio- Install dependencies:
npm install
# or
yarn install
# or
bun install- Set up environment variables:
Create a .env file in the root directory:
VITE_FORMSPREE_ENDPOINT=https://formspree.io/f/YOUR_FORM_ID- Start the development server:
npm run dev
# or
yarn dev
# or
bun devThe application will be available at http://localhost:8080
The contact form uses Formspree for handling submissions:
-
Sign up for Formspree:
- Visit https://formspree.io/
- Create a free account
-
Create a new form:
- Click "New Form" in your dashboard
- Name it (e.g., "Portfolio Contact")
- Copy the endpoint URL:
https://formspree.io/f/YOUR_FORM_ID
-
Configure environment:
- Add to
.env:VITE_FORMSPREE_ENDPOINT=https://formspree.io/f/YOUR_FORM_ID
- Add to
-
Test it:
- Submit the contact form
- Check your Formspree dashboard for the submission
Fallback: If not configured, the form will open your default email client.
npm run build
# or
yarn build
# or
bun run buildBuilt files will be in the dist directory.
| Script | Description |
|---|---|
npm run lint |
Run ESLint |
npm run build:dev |
Build in development mode |
npm run preview |
Preview production build |
npm run preview
# or
yarn preview
# or
bun run previewThe project includes production-ready Docker support for easy containerized deployment.
# Build and run the container
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the container
docker-compose downThe application will be available at http://localhost:3000
# Build the image
docker build -t portfolio-app .
# Run the container
docker run -p 3000:80 portfolio-app
# Run in detached mode with a name
docker run -d -p 3000:80 --name portfolio portfolio-app
# View logs
docker logs -f portfolio
# Stop the container
docker stop portfolio
# Remove the container
docker rm portfolio- Multi-stage Build - Optimized image size (~50MB)
- Nginx Server - Fast static file serving with gzip compression
- Health Checks - Automatic container health monitoring
- Security - Non-root user, minimal attack surface
- SPA Routing - Proper handling of client-side routes
- Performance - Asset caching headers and compression
- Networking - Isolated network for multi-container setups
To pass environment variables to the Docker container:
# Using docker-compose with .env file
docker-compose up -d --env-file .env.production
# Using docker run
docker run -p 3000:80 --env-file .env.production portfolio-app
# Or pass individual variables
docker run -p 3000:80 -e VITE_FORMSPREE_ENDPOINT=https://formspree.io/f/YOUR_ID portfolio-appScale the service:
docker-compose up -d --scale web=3Use a custom port:
# Edit docker-compose.yml or override via command
docker-compose -f docker-compose.yml up -d -e "PORT=8080"View container status:
docker-compose psContainer exits immediately:
docker logs portfolio-appPort already in use:
# Change port in docker-compose.yml or use:
docker run -p 8080:80 portfolio-appRebuild without cache:
docker-compose build --no-cache
docker-compose up -dCheck container health:
docker ps --format "table {{.Names}}\t{{.Status}}"Deploy to any static hosting platform:
npm i -g vercel
vercelnpm run build
# Drag and drop the 'dist' folder to Netlifynpm run build
# Push 'dist' folder to gh-pages branch- Connect your GitHub repository
- Build command:
npm run build - Output directory:
dist
GitHub Actions runs on every push and pull request to main / master:
- Lint β ESLint
- Build β
npm run build
Workflow: .github/workflows/ci.yml
starlight-portfolio/
βββ .github/
β βββ workflows/
β βββ ci.yml # GitHub Actions CI
βββ src/
β βββ components/ # React components
β β βββ ui/ # shadcn/ui components
β β βββ AboutSection.tsx
β β βββ AnimatedBackground.tsx
β β βββ BackToTop.tsx
β β βββ BlurText.tsx
β β βββ ContactSection.tsx
β β βββ Footer.tsx
β β βββ Galaxy.tsx
β β βββ HeroSection.tsx
β β βββ Navbar.tsx
β β βββ ProjectsSection.tsx
β β βββ SkillsSection.tsx
β β βββ StarBackground.tsx
β β βββ UfoIcon.tsx
β βββ contexts/
β β βββ ThemeContext.tsx
β βββ hooks/
β β βββ useScrollAnimation.ts
β β βββ useTypingEffect.ts
β β βββ use-toast.ts
β βββ lib/
β β βββ ufoMusic.ts
β β βββ utils.ts
β βββ pages/
β β βββ Index.tsx
β β βββ NotFound.tsx
β βββ App.tsx
β βββ index.css
β βββ main.tsx
βββ public/ # Static assets
βββ Dockerfile
βββ docker-compose.yml
βββ package.json
Edit src/index.css to change the color scheme:
:root {
--background: 0 0% 100%; /* White */
--foreground: 0 0% 10%; /* Near Black */
--muted-foreground: 0 0% 45%; /* Gray */
}- Personal Info: Edit
src/components/HeroSection.tsx - About Text: Edit
src/components/AboutSection.tsx - Skills: Edit
src/components/SkillsSection.tsx - Projects: Edit
src/components/ProjectsSection.tsx - Contact: Edit
src/components/ContactSection.tsx
- Scroll Animations: Change
transitionDelayin component files - Hover Effects: Adjust transition durations in Tailwind classes
- β‘ Lighthouse Score: 95+
- π First Contentful Paint: < 1s
- π¦ Bundle Size: ~130KB gzipped
- βΏ Accessibility: WCAG 2.1 AA compliant
This project is open source and available under the MIT License.
Contributions, issues, and feature requests are welcome!
Mohammed Hassan
- Website: hassancodes.in
- GitHub: @hassarch
- LinkedIn: hassan0777
β Star this repo if you found it helpful!