GitHub sorts repositories by "last updated" date. This means your most important projects can get buried when you make a small fix to an old repo or create a new experimental project.
GitPins solves this by automatically updating the "last updated" timestamp of your chosen repositories, keeping them at the top of your profile.
- Drag & Drop Ordering - Visually arrange your repositories in the order you want
- Smart Sync - Only creates commits when order changes (no unnecessary commits!)
- Commit Cleanup - Remove old GitPins commits to keep your history clean
- Two Commit Strategies - Choose between "revert" (cleaner history) or "branch" (more commits)
- Configurable Frequency - Sync every 1, 2, 4, 6, 8, 12, or 24 hours
- Private Repos Support - Include or exclude private repositories
- Bilingual UI - Available in English and Spanish
- Dark/Light Mode - Automatic theme detection with manual override
- Open Source - Self-host or contribute
- Connect with GitHub - Authenticate and install the GitPins GitHub App
- Arrange Your Repos - Drag and drop to set your preferred order
- Activate Sync - GitPins creates a config repo with a GitHub Action
- Automatic Updates - The Action periodically "bumps" your repos to maintain order
GitPins uses empty commits to update the "last updated" timestamp:
Revert Strategy (Recommended):
git commit --allow-empty -m "gitpins: bump"
git revert HEAD --no-edit
git pushBranch Strategy:
git checkout -b gitpins-temp
git commit --allow-empty -m "gitpins: sync"
git checkout main && git merge gitpins-temp
git branch -d gitpins-temp && git pushGitPins is designed with security in mind:
- Minimal Permissions - Only requests access to repository contents (for empty commits)
- No Code Access - Cannot read, modify, or delete your actual code
- Encrypted Tokens - Access tokens are encrypted with AES-256-GCM
- Open Source - Full code transparency
- Create empty commits in your repositories
- Create the
gitpins-configrepository - Read repository metadata (name, stars, etc.)
- Read your source code
- Modify existing files
- Delete repositories or branches
- Access other GitHub data
- Framework: Next.js 16 (App Router)
- Language: TypeScript 5
- Database: PostgreSQL (via Prisma 7)
- Auth: GitHub OAuth (GitHub Apps)
- Styling: Tailwind CSS 4
- Drag & Drop: dnd-kit
- Deployment: Vercel
- Node.js 18+
- PostgreSQL database
- GitHub App
Neon offers a generous free tier perfect for GitPins:
- Free tier: 0.5 GB storage, 190 compute hours/month
- Serverless: Scales to zero when not in use
- Fast: Optimized for serverless environments like Vercel
- Easy setup: Create a database in seconds
Other compatible options: Supabase, PlanetScale, Railway, or any PostgreSQL provider.
Go to GitHub Developer Settings and create a new app.
For Production:
| Field | Value |
|---|---|
| Homepage URL | https://your-domain.com |
| Callback URL | https://your-domain.com/api/auth/callback |
| Setup URL (optional) | https://your-domain.com/api/auth/setup |
| Webhook URL | Leave empty (not required) |
| Webhook Active | ❌ Unchecked |
For Local Development:
| Field | Value |
|---|---|
| Homepage URL | http://localhost:3000 |
| Callback URL | http://localhost:3000/api/auth/callback |
| Setup URL (optional) | http://localhost:3000/api/auth/setup |
| Webhook URL | Leave empty |
| Webhook Active | ❌ Unchecked |
Note: You can update these URLs later. For local development, you'll need to use localhost URLs.
Configure these permissions in your GitHub App settings:
Repository Permissions:
| Permission | Access Level | Purpose |
|---|---|---|
| Actions | Read and write | Enable/disable workflows in repos |
| Administration | Read and write | Enable GitHub Actions on config repo |
| Contents | Read and write | Create empty commits for ordering |
| Metadata | Read-only | Read repository list and info |
| Secrets | Read and write | Create GITPINS_SYNC_SECRET |
| Workflows | Read and write | Create and manage the sync workflow |
Account Permissions:
| Permission | Access Level | Purpose |
|---|---|---|
| Email addresses | Read-only | Get user email for identification |
In the OAuth section of your GitHub App:
- Request user authorization (OAuth) during installation: ✅ Enabled
- Enable Device Flow: Optional
git clone https://github.com/686f6c61/gitpins.git
cd gitpins
npm installcp .env.example .envEdit .env with your values:
DATABASE_URL="postgresql://..."
DIRECT_URL="postgresql://..."
GITHUB_APP_ID="your_app_id"
GITHUB_APP_CLIENT_ID="your_client_id"
GITHUB_APP_CLIENT_SECRET="your_client_secret"
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----..."
NEXT_PUBLIC_APP_URL="https://your-domain.com"
JWT_SECRET="generate_with_openssl_rand_base64_32"
ENCRYPTION_SECRET="generate_with_openssl_rand_base64_32"
ADMIN_GITHUB_ID="your_github_user_id"npx prisma db push# Development
npm run dev
# Production
npm run build
npm startWhen running locally:
- Update your GitHub App URLs to use
http://localhost:3000 - Set environment variable:
NEXT_PUBLIC_APP_URL=http://localhost:3000 - Re-authenticate: Log out and log back in after changing URLs to get a fresh OAuth token with correct scopes
When authenticating, GitPins requests these OAuth scopes:
repo- Full control of private repositories (needed to create the config repo)user:email- Access to email address
If you're experiencing "Resource not accessible by integration" errors, the user needs to re-authenticate to get a token with the correct scopes.
| Issue | Solution |
|---|---|
| "Resource not accessible" | Re-authenticate (logout/login) to refresh OAuth token |
| "Bad credentials" | Check GITHUB_APP_PRIVATE_KEY format (include BEGIN/END lines) |
| Actions not running | Enable Actions in the gitpins-config repo settings |
| Repos not syncing | Check Actions tab in gitpins-config for workflow errors |
- Click the button above
- Add a PostgreSQL database (Neon recommended)
- Configure environment variables
- Deploy!
GitPins includes an admin dashboard for managing users and viewing statistics.
-
Get your GitHub User ID:
curl https://api.github.com/users/YOUR_USERNAME | grep '"id"'
-
Set the environment variable:
ADMIN_GITHUB_ID="your_numeric_github_id"
-
Access the dashboard: Navigate to
/adminafter logging in with the admin account.
- User Statistics: Total users, active users, banned users, sync counts
- User Management: View all users with their config repos and activity
- Ban/Unban Users: Suspend users who violate terms of service
- Delete Users: Remove users from the application (they can re-register)
- Activity Charts: Visual graphs of registrations and syncs over 30 days
The admin panel is protected by:
- Session validation (must be logged in)
- GitHub ID verification against
ADMIN_GITHUB_ID - All admin API endpoints return 403 Forbidden for non-admin users
src/
├── app/ # Next.js App Router
│ ├── api/ # API Routes
│ │ ├── auth/ # OAuth endpoints
│ │ ├── repos/ # Repository management
│ │ ├── config/ # Config repo creation
│ │ └── sync/ # Sync endpoint (called by GitHub Action)
│ ├── dashboard/ # Main dashboard
│ ├── admin/ # Admin panel
│ └── how-it-works/ # Documentation page
├── components/ # React components
├── lib/ # Utility modules
│ ├── crypto.ts # AES-256-GCM encryption
│ ├── session.ts # JWT session management
│ ├── security.ts # CSRF, rate limiting
│ ├── github.ts # GitHub OAuth
│ └── github-app.ts # GitHub App operations
├── i18n/ # Internationalization
└── types/ # TypeScript definitions
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
686f6c61 - @686f6c61
Made with code and mass energy by @686f6c61
If you find this useful, consider giving it a star!




