A full-stack GitHub-inspired platform built with the MERN stack β supporting real Git operations, issues, pull requests, commit history, branch management, and real-time notifications.
Warning
- Overview
- Tech Stack
- Features
- Project Structure
- Prerequisites
- Environment Setup
- Installation & Running
- API Reference
- Git Operations
- Real-Time Events
- Contributing
GitHub Clone is a self-hosted, open-source code collaboration platform. It replicates core GitHub workflows β from creating repositories and committing files to reviewing diffs, managing branches, raising issues, and merging pull requests β all powered by real Git internals via isomorphic-git and node-git-server.
| Technology | Purpose |
|---|---|
| React 19 | UI framework |
| Vite 8 | Development server & build tool |
| TailwindCSS 4 | Utility-first styling |
| React Router DOM 7 | Client-side routing |
| Socket.io Client | Real-time notifications |
| Lucide React | Icon library |
| React Markdown | Render markdown files (README preview) |
| React Diff View | Syntax-highlighted diff rendering |
| React Calendar Heatmap | Contribution activity graph |
| Luxon | Date/time formatting |
| Axios | HTTP client |
| Technology | Purpose |
|---|---|
| Node.js + Express 5 | REST API server |
| MongoDB + Mongoose 9 | Database & ODM |
| isomorphic-git | Server-side Git operations (commit, diff, branches) |
| node-git-server | Git HTTP smart protocol (clone, push, pull over HTTP) |
| Socket.io | Real-time WebSocket events |
| JSON Web Token (JWT) | Authentication & authorization |
| bcryptjs | Password hashing |
| dotenv | Environment variable management |
| fs-extra | Enhanced file system operations |
| cors | Cross-Origin Resource Sharing |
- π Authentication β Register, login, JWT-based session management
- π Repository Management β Create repos, browse file tree, view file contents
- πΏ Branch Management β Create branches, switch branches, compare refs
- π Commit System β Server-side commits via
isomorphic-git, full commit log with diff view - π Pull Requests β Create PRs, view diffs between branches, check mergeability, merge
- π Issues β Open issues, add comments, update open/closed status
- π‘ Real-Time Notifications β Socket.io broadcasts when a PR is merged
- π€ Profile Page β View user profile and contribution graph
- π README Preview β Auto-renders
README.mdon repo home page - π Git over HTTP β Real
git clone,git push,git pullvia the/gitendpoint
github-clone/
βββ client/ # React frontend (Vite)
β βββ src/
β β βββ components/
β β β βββ Navbar.jsx
β β β βββ Dashboard.jsx
β β β βββ Login.jsx
β β β βββ Register.jsx
β β β βββ RepoView.jsx
β β β βββ FileExplorer.jsx
β β β βββ CommitHistory.jsx
β β β βββ DiffView.jsx
β β β βββ IssueList.jsx
β β β βββ IssueDetail.jsx
β β β βββ PullRequestList.jsx
β β β βββ PullRequestDetails.jsx
β β β βββ CreatePullRequest.jsx
β β β βββ CreateRepoModal.jsx
β β β βββ ProfilePage.jsx
β β β βββ ContributionGraph.jsx
β β βββ App.jsx
β β βββ main.jsx
β βββ package.json
β βββ vite.config.js
β
βββ server/ # Express backend
β βββ controllers/ # Business logic
β βββ middleware/ # Auth middleware (JWT)
β βββ models/ # Mongoose schemas
β β βββ User.js
β β βββ Repository.js
β β βββ Issue.js
β β βββ PullRequest.js
β βββ routes/ # API route definitions
β β βββ authRoutes.js
β β βββ repoRoutes.js
β β βββ issueRoutes.js
β β βββ userRoutes.js
β βββ gitServer.js # node-git-server config
β βββ index.js # Entry point
β
βββ repositories/ # Bare Git repos (auto-created)
Make sure the following are installed on your system before proceeding:
- Node.js
>= 18.xβ Download - npm
>= 9.x(comes with Node.js) - Git
>= 2.xβ Download - MongoDB β Either local install or a free MongoDB Atlas cluster
Create a .env file inside the server/ directory:
# βββ Server ββββββββββββββββββββββββββββββββββββββββββββββββ
PORT=5000
# βββ MongoDB βββββββββββββββββββββββββββββββββββββββββββββββ
# Option 1: Local MongoDB
MONGODB_URI=mongodb://localhost:27017/github-clone
# Option 2: MongoDB Atlas (recommended)
MONGODB_URI=mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/github-clone?retryWrites=true&w=majority
# βββ JWT βββββββββββββββββββββββββββββββββββββββββββββββββββ
JWT_SECRET=your_super_secret_key_change_this_in_production
JWT_EXPIRES_IN=7d| Variable | Required | Description |
|---|---|---|
PORT |
No | Port for Express server. Defaults to 5000 |
MONGODB_URI |
Yes | MongoDB connection string |
JWT_SECRET |
Yes | Secret key for signing JWT tokens. Use a long random string in production |
JWT_EXPIRES_IN |
No | Token expiry duration. Defaults to 7d |
Tip
Generate a strong JWT secret with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
# βββ Backend Base URL ββββββββββββββββββββββββββββββββββββββ
VITE_API_BASE_URL=http://localhost:5000Note
If you change the server port, update VITE_API_BASE_URL and the Socket.io connection URL in client/src/App.jsx accordingly.
git clone https://github.com/<your-username>/github-clone.git
cd github-clone# Install server dependencies
cd server
npm install
# Install client dependencies
cd ../client
npm installThe git server stores bare repos here. Create it at the project root:
mkdir -p ../repositoriescd server
node index.jsExpected output:
MongoDB Connected
Server is running on port 5000
Open a new terminal tab:
cd client
npm run devExpected output:
VITE v8.x.x ready in xxx ms
β Local: http://localhost:5173/
Open http://localhost:5173 in your browser.
All API endpoints are prefixed with /api/v1. Protected routes require an Authorization: Bearer <token> header.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/auth/signup |
β | Register a new user |
POST |
/api/v1/auth/login |
β | Login and receive a JWT token |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/repos/init |
β | Initialize a new repository |
GET |
/api/v1/repos/user/mine |
β | List current user's repositories |
GET |
/api/v1/repos/:repoId |
β | Get repository details |
GET |
/api/v1/repos/:repoId/files |
β | List all files in HEAD branch |
POST |
/api/v1/repos/:repoId/commit |
β | Write, stage, and commit changes |
GET |
/api/v1/repos/:repoId/commits |
β | Get full commit history |
GET |
/api/v1/repos/:repoId/commits/:sha/diff |
β | Get diff for a specific commit |
GET |
/api/v1/repos/:repoId/branches |
β | List all branches |
POST |
/api/v1/repos/:repoId/branches |
β | Create a new branch |
GET |
/api/v1/repos/:repoId/compare/:base/:head |
β | Compare two branches |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/repos/:repoId/prs |
β | List all pull requests |
POST |
/api/v1/repos/:repoId/prs |
β | Create a new pull request |
GET |
/api/v1/repos/:repoId/prs/:prId/mergeable |
β | Check if PR is mergeable |
POST |
/api/v1/repos/:repoId/prs/:prId/merge |
β | Merge a pull request |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/issues/:repositoryId |
β | Open a new issue |
GET |
/api/v1/issues/repo/:repoId |
β | List all issues for a repo |
GET |
/api/v1/issues/:issueId |
β | Get issue details & comments |
POST |
/api/v1/issues/:issueId/comments |
β | Add a comment to an issue |
PATCH |
/api/v1/issues/:issueId/status |
β | Update issue status (open/closed) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/users/:username |
β | Get public profile of a user |
This project supports real Git operations over HTTP using the Git smart HTTP protocol.
Once a repository is created via the API, you can interact with it using standard Git commands:
# Clone a repository
git clone http://localhost:5000/git/<repo-name>
# Add a remote to an existing local repo
git remote add origin http://localhost:5000/git/<repo-name>
# Push changes
git push origin main
# Pull latest changes
git pull origin mainNote
<repo-name> refers to the bare repository name stored in the repositories/ directory on the server. This is initialized automatically when you create a repo via the API.
The server uses Socket.io for real-time communication. The client connects to http://localhost:5000 on app load.
| Event | Direction | Description |
|---|---|---|
join_repo |
Client β Server | Join a repository's room to receive its events |
pr_merged |
Server β Client | Emitted to all room members when a PR is merged |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feat/amazing-feature - Commit your changes:
git commit -m "feat: add amazing feature" - Push to the branch:
git push origin feat/amazing-feature - Open a Pull Request on GitHub
Found a bug or a frontend issue? Please open an issue with:
- A clear title and description
- Steps to reproduce
- Expected vs. actual behavior
- Screenshots if applicable
Note
There are currently some known issues on the frontend side. I'm working on them in my free time β feel free to open an issue or submit a PR if you spot something! π
This project is open-source and available under the MIT License.
Built with β€οΈ as a learning project β inspired by GitHub.