How it works
GitFolio is built as a modern monorepo with multiple specialized applications working together to deliver a seamless portfolio experience. This guide explains the core architecture and data flow.Architecture overview
GitFolio consists of four main applications:- Web app (
apps/web) - Main dashboard and authentication built with Next.js 16 - Renderer (
apps/renderer) - Dedicated portfolio rendering engine - Server (
apps/server) - Express.js backend API for data operations - Worker (
apps/worker) - Background job processing for scheduled tasks
All applications are deployed independently and communicate via REST APIs, allowing for horizontal scaling and isolated deployments.
GitHub synchronization
GitFolio uses the GitHub REST API to fetch and sync your profile data. Here’s how it works:Initial onboarding flow
When you complete onboarding, GitFolio performs the following steps:Authentication
Depending on your sign-up method:
- GitHub OAuth: GitFolio obtains an OAuth access token from Clerk, which is used to make authenticated requests to the GitHub API on your behalf
- Google/Email: GitFolio uses a service account token to make public API requests to GitHub
@clerk/backend SDK to securely manage OAuth tokens.Fetch user details
GitFolio calls the GitHub API endpoint:This retrieves:
- Username
- Bio
- Location
- Website URL
- Followers/following counts
- Profile creation date
- Avatar URL
User table in the PostgreSQL database.Fetch repositories
GitFolio fetches all your repositories:For each repository, GitFolio makes additional API calls to fetch:
- Languages: Via the
languages_urlendpoint to get language breakdown - Deployments: Via the
deployments_urlendpoint to count active deployments
- Name, description, and topics
- Stars, forks, and deployment counts
- Repository and homepage links
- Creation, update, and last push timestamps
- Language composition (stored as JSON)
Repo table with a foreign key to your user ID.The entire onboarding sync process is handled by the
onBoardingProcess function in apps/server/src/Services/onboarding.service.ts.Automated daily sync
GitFolio runs a scheduled cron job to keep your user data synchronized:- Fetches all users from Clerk (the authentication provider)
- Compares with users in the GitFolio database
- Creates missing user records
- Sends welcome emails to new users via a Bull queue
Portfolio rendering system
When someone visits your portfolio atportfolio.gitfolio.in/{username}, here’s what happens:
Data fetching
Server request
The renderer app (This endpoint (
apps/renderer) makes a request to the backend API:apps/server/src/Controllers/renderer.controller.ts) queries the database for:- User profile information
- All repositories where
isIncluded = true - Work experience entries
- Education history
- Social links (stored as JSON)
- Skills array
Data transformation
The raw database records are transformed into a standardized This ensures a consistent interface for all templates.
DATA type structure:Template selection
The renderer looks up your active template ID from
personalInfo.activeTemplateId and matches it against the template registry in packages/templates/src/metaData.ts.If no template is set or the template isn’t found, a “No Template Activated” error is displayed.SEO and metadata
Every portfolio page generates dynamic metadata for SEO and social sharing:- Search engines can properly index your portfolio
- Social media platforms display rich previews with your name and avatar
- Each page has unique title and description tags
Template system
GitFolio’s template system is built on a plugin-like architecture:Template structure
Each template lives inpackages/templates/src/Templates/{TemplateName}/ and consists of:
- Template.tsx - The main React component that receives portfolio data
- Components/ - Template-specific UI components
Theme support
Templates can support:- Light only - Single light color scheme
- Dark only - Single dark color scheme
- Both - Toggleable light/dark modes using
next-themes
Template activation
When you activate a template:-
Dashboard sends a POST request to update your user record:
-
The
activeTemplateIdfield in your User record is updated - Next time someone views your portfolio, the new template is rendered
Template changes are instant. No build or deployment process is required.
Data storage
GitFolio uses PostgreSQL with Prisma ORM. Key database models:User model
Repository model
The
isIncluded flag allows you to hide repositories from your portfolio without deleting them from the database.Image uploads and storage
Custom images (profile pictures, project thumbnails, company logos) are stored in AWS S3:Upload to S3
The client receives a presigned URL and uploads the image directly to S3:This bypasses the server for large file uploads, improving performance.
Presigned URLs are generated using the
@aws-sdk/s3-request-presigner package and are valid for a limited time for security.Authentication flow
GitFolio uses Clerk for authentication with JWT-based API authorization:- User signs in via Clerk (GitHub OAuth, Google, or Email)
- Clerk issues a session token
- Dashboard requests a JWT token:
await getToken() - All API requests include:
Authorization: Bearer {token} - Server validates tokens using
@clerk/backendmiddleware - Invalid tokens return 401 Unauthorized
Technology stack
GitFolio is built with modern technologies:- Frontend: React 19, Next.js 16, TailwindCSS 4
- Backend: Express.js, Node.js
- Database: PostgreSQL with Prisma ORM
- Authentication: Clerk
- Storage: AWS S3 with CloudFront
- Deployment: Vercel (frontend), Railway/Render (backend)
- Package manager: pnpm workspaces (monorepo)
Next steps
Dashboard guide
Learn to use all dashboard features
API reference
Explore GitFolio’s REST API endpoints
Template development
Build your own custom templates
FAQ
Common issues and solutions