Skip to content

jennings/pulldash

Repository files navigation

pulldash logo Pulldash

GitHub Release GitHub License GitHub Actions Workflow Status

Fast, filterable PR review. Entirely client-side.

Warning

Pulldash is WIP. Expect bugs.

Try It

Browser: pr.jennings.io. Open pull requests at https://pr.jennings.io/<owner>/<repo>/pull/<number>.

Example

Features

  • Custom filters: Add repos and filter by review requests, authored PRs, or all activity.

    Filtering PRs

  • Keyboard-driven: j/k to navigate files, arrows for lines, c to comment, s to submit.

    Keybinds

  • Fast file search: Ctrl+K to fuzzy-find across hundreds of changed files.

    Search

Why

  • GitHub's review UI is slow (especially for large diffs)
  • No central view to filter PRs you care about
  • AI tooling has produced more PRs than ever before—making a snappy review UI essential

How It Works

GitHub's API supports CORS, so Pulldash runs entirely client-side. No backend proxying your requests.

  • Web Worker pool: Diff parsing and syntax highlighting run in workers sized to navigator.hardwareConcurrency. The main thread stays free for scrolling.

  • Pre-computed navigation: When a diff loads, we index all navigable lines. Arrow keys are O(1)—no DOM queries.

  • External store: State lives outside React (useSyncExternalStore). Focusing line 5000 doesn't re-render the file tree.

  • Virtualized rendering: Diffs, file lists, and the command palette only render visible rows.

Setup (self-hosted)

1. Choose the application type

App type Flow Server config Token storage
PAT Static localStorage
OAuth App Device GITHUB_CLIENT_ID localStorage
Web + GITHUB_CLIENT_SECRET localStorage
GitHub App Device GITHUB_CLIENT_ID Access token in memory, refresh token in localStorage
Web + GITHUB_CLIENT_SECRET Access token in memory, refresh token in localStorage

PAT — The user generates a classic GitHub PAT on github and paste it in the UI.

Use the repo scope for private repos, or public_repo for public repos only.

Only a static server is required.

Device flow — The user is presented with a code to copy/paste on github.

No client secret needed. The device flow is ideal for admins who don't want to manage a client secret.

Web flow — The user is redirected to github to authorize the application.

Requires a client secret on the server.

The token storage depends on the application type (OAuth App vs GitHub App), not on the flow.

2. Create an application

PAT — No setup needed.

OAuth App (device flow)

  1. Go to GitHub Settings → Developer settings → New OAuth App
  2. Fill in:
    • Application name: pulldash (or any name)
    • Homepage URL: your pulldash URL (e.g. http://localhost:3002)
    • Authorization callback URL: {your-url}/api/auth/callback (e.g. http://localhost:3002/api/auth/callback)
    • Enable Device Flow: check this box
  3. Click Register application
  4. Copy the Client ID

OAuth App (web flow)

  1. Go to GitHub Settings → Developer settings → New OAuth App
  2. Fill in:
    • Application name: pulldash (or any name)
    • Homepage URL: your pulldash URL (e.g. http://localhost:3002)
    • Authorization callback URL: {your-url}/api/auth/callback (e.g. http://localhost:3002/api/auth/callback)
  3. Click Register application
  4. Copy the Client ID
  5. Generate a Client Secret and copy it

GitHub App (recommended)

Use the creation script:

bun run scripts/create-github-app.ts

It will ask for your pulldash URL, open a pre-configured GitHub App creation page, and print the environment variables to set on your server.

GitHub Apps also support the device flow — after creation, go to the app's settings page and check Enable Device Flow.

3. Run the server

PAT

Just serve the files with you preferred web server.

Device flow

export GITHUB_CLIENT_ID=your_client_id
bun run src/node/main.ts

Web flow

export GITHUB_CLIENT_ID=your_client_id
export GITHUB_CLIENT_SECRET=your_secret
bun run src/node/main.ts

The frontend fetches the Client ID and available flows from the server's GET /api/auth/config endpoint at runtime — no rebuild needed when changing the OAuth App configuration.

Development

bun install
bun dev

Then open http://localhost:3002 (or the next available port if 3002 is in use).

To run the server without the build watcher:

bun run build:browser
bun run src/node/main.ts

Docker

Build and run with Docker:

docker build -t pulldash .
docker run -p 3002:3002 \
  -e GITHUB_CLIENT_ID=your_client_id \
  -e GITHUB_CLIENT_SECRET=your_secret \
  pulldash

License

AGPL

About

Review pull requests in a high-performance UI, driven by keybinds.

Resources

License

Stars

Watchers

Forks

Contributors