← All projects

TypeScript · Updated 2026

Repo Deleter

Bulk delete GitHub repositories instantly. Secure, fast, no data stored.

R

GitHub Repo Cleaner

A secure web application to bulk delete GitHub repositories. Sign in with GitHub, select repos, and delete them instantly.

Try it out here: https://repo-deleter.xyz

Features

  • Bulk Selection: Search, filter, and select multiple repositories at once
  • Fast Deletion: Delete up to 100 repositories in a single action with concurrent processing
  • Secure: No database, no data storage. Your token is encrypted in an HTTP-only cookie
  • User-Owned Only: Only shows repositories you own (excludes organization repos)
  • Retry Failed: If any deletions fail, easily retry them
  • Beautiful UI: Modern, responsive design with dark mode support

Tech Stack

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript
  • Styling: Tailwind CSS
  • Auth: NextAuth.js with GitHub OAuth
  • GitHub API: Octokit
  • Validation: Zod
  • Analytics: Vercel Analytics
  • Hosting: Vercel

Prerequisites

  • Node.js 20+
  • A GitHub account
  • A GitHub OAuth App

Environment Variables

| Variable | Description | |----------|-------------| | NEXTAUTH_URL | Your app's URL (e.g., http://localhost:3000 for dev) | | NEXTAUTH_SECRET | A random string for session encryption | | GITHUB_ID | Your GitHub OAuth App Client ID | | GITHUB_SECRET | Your GitHub OAuth App Client Secret |

Setup

1. Create a GitHub OAuth App

  1. Go to GitHub Developer Settings
  2. Click New OAuth App
  3. Fill in the details:
    • Application name: GitHub Repo Cleaner (or your choice)
    • Homepage URL: http://localhost:3000 (for development)
    • Authorization callback URL: http://localhost:3000/api/auth/callback/github
  4. Click Register application
  5. Copy the Client ID
  6. Click Generate a new client secret and copy it

2. Configure Environment

# Copy the example env file
cp .env.example .env.local

# Edit .env.local with your values

Your .env.local should look like:

NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-generated-secret
GITHUB_ID=your-github-client-id
GITHUB_SECRET=your-github-client-secret

Generate a secret:

openssl rand -base64 32

3. Install Dependencies

npm install

4. Run Development Server

npm run dev

Open http://localhost:3000 in your browser.

Security

What This App Does

  • Uses GitHub OAuth for authentication (no passwords stored)
  • Fetches your repository list from GitHub's API
  • Deletes repositories using GitHub's API when you confirm
  • Stores your access token in an encrypted HTTP-only session cookie

What This App Does NOT Do

  • Store any data in a database
  • Log repository names or sensitive information
  • Share your data with third parties
  • Access organization repositories

Session Security

  • Session expires after 1 hour
  • Cookies are HTTP-only (not accessible via JavaScript)
  • Cookies use SameSite=Lax for CSRF protection
  • Cookies are Secure in production (HTTPS only)
  • Token is encrypted in the JWT

Revoking Access

You can revoke this app's access anytime:

  1. Go to GitHub Settings > Applications
  2. Find "GitHub Repo Cleaner"
  3. Click Revoke

Limitations

  • User-owned repos only: Organization repositories are not shown
  • 100 repos per action: Maximum bulk delete limit
  • Rate limits: Subject to GitHub API rate limits (5,000 requests/hour for authenticated users)
  • No recovery: Deleted repositories cannot be recovered

Project Structure

src/
├── app/
│   ├── api/
│   │   ├── auth/[...nextauth]/  # NextAuth API route
│   │   ├── repos/               # Repo listing API
│   │   └── delete/              # Repo deletion API
│   ├── dashboard/               # Protected dashboard page
│   ├── privacy/                 # Privacy policy
│   ├── terms/                   # Terms of service
│   ├── layout.tsx               # Root layout with providers
│   ├── page.tsx                 # Landing page
│   ├── robots.ts                # robots.txt
│   └── sitemap.ts               # sitemap.xml
├── components/
│   ├── Button.tsx               # Reusable button
│   ├── ConfirmModal.tsx         # Deletion confirmation modal
│   ├── Header.tsx               # App header
│   ├── Providers.tsx            # Session provider wrapper
│   ├── RepoTable.tsx            # Repository table
│   ├── ResultsSummary.tsx       # Deletion results
│   ├── Toast.tsx                # Toast notifications
│   └── Toolbar.tsx              # Search/sort/delete toolbar
├── lib/
│   ├── auth.ts                  # NextAuth configuration
│   ├── github.ts                # GitHub API functions
│   └── validation.ts            # Zod schemas
└── types/
    └── index.ts                 # TypeScript types

API Routes

GET /api/repos

Returns the authenticated user's repositories.

Response:

{
  "repos": [
    {
      "id": 123,
      "name": "my-repo",
      "full_name": "username/my-repo",
      "private": false,
      "fork": false,
      "is_template": false,
      "updated_at": "2024-01-15T10:30:00Z",
      "created_at": "2024-01-01T10:00:00Z",
      "html_url": "https://github.com/username/my-repo",
      "description": "My repository"
    }
  ]
}

POST /api/delete

Deletes the specified repositories.

Request:

{
  "full_names": ["username/repo1", "username/repo2"]
}

Response:

{
  "results": [
    {
      "full_name": "username/repo1",
      "ok": true,
      "status": 204,
      "message": "Deleted successfully"
    },
    {
      "full_name": "username/repo2",
      "ok": false,
      "status": 403,
      "message": "Rate limited or insufficient permissions"
    }
  ]
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - feel free to use this project for any purpose.

Disclaimer

This application is not affiliated with, endorsed by, or connected to GitHub, Inc. Use at your own risk. Always ensure you have backups of important repositories before deletion.