The bulk operations and sprint tooling that GitHub Projects V2 should have shipped with — running entirely in your browser, your token never leaves your machine.
Refined GitHub Projects fixes the gaps that slow down every sprint planning session.
Native GitHub lets you update exactly one item's field per interaction. With a backlog of 60 items, that's 60 clicks just to flip a Status.
The built-in duplicate copies only the title. Every assignee, label, status, and project field has to be re-applied manually — every single time.
Moving incomplete items to the next iteration requires opening each issue individually, changing the sprint field, and hoping you didn't miss any.
When you do find a workaround — via API or script — there's no progress indicator, no rate-limit safety, and a 403 ban if you fire too fast.
Checkboxes appear on every row the moment you hover. Select individual items or press ⌘A to grab everything visible. The floating Actions bar appears instantly — open the full menu to access all 11 bulk operations, grouped by category.
A guided 3-step wizard for bulk-updating Status, Priority, Sprint, Estimate, Assignees, Labels & more. Choose which fields to update, set new values for every field type, then review a clean diff of every change before a single API call fires.
GitHub's built-in copy pastes only the title. Deep Duplicate clones everything — all project fields, assignees, labels, and body — so you don't have to re-apply anything. Review and edit every field in an editable modal before you confirm.
The Sprint widget appears top-right on every Projects page. One click ends the sprint and auto-moves all incomplete items to the next iteration. The background queue handles everything sequentially and rate-limit safe, with live progress shown in real time.
One extension. Eleven features. Zero extra tabs. One token stays local.
Bulk-update Status, Priority, Sprint, Size, Estimate, Assignees, Labels, and custom fields
⌘⇧EUpdate issue or PR titles across multiple items at once
⌘⇧RReposition selected items within your project board
⌘⇧JMark as Completed or Not Planned. Sweep a whole sprint in one action.
⌘⇧XRestore closed items back to open. Only affects actually-closed issues.
⌘⇧OLock with reason: off-topic, too heated, resolved, or spam
⌘⇧LPromote or demote important issues at the repository level (max 3)
⌘⇧FMove issues to another repository with full history intact
⌘⇧MDownload selected items with all fields, assignees, labels, and custom properties
⌘⇧VClone any item with all fields, assignees, labels, body, and sub-issue relationships
Permanently remove items from your project. Requires admin access.
⌘⇧⌫One click moves all incomplete items to the next iteration automatically
Go to the Releases page and download the browser build package (not the source archive). Extract it on your machine.
Chrome / Edge: chrome://extensions
Firefox:
about:debugging#/runtime/this-firefox
Chrome / Edge: enable Developer mode, click Load
unpacked, select the extracted folder.
Firefox: click Load
Temporary Add-on, select the manifest file.
Click the extension icon, paste your token, and click Validate and save. All features unlock automatically — one token for everything.
api.github.com.
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic)
Generate token →Node.js 18+ and pnpm required.
# Clone the repository git clone https://github.com/fathiraz/refined-github-projects.git cd refined-github-projects # Install dependencies pnpm install # Start dev server with hot reload pnpm dev # Production build pnpm build # Type check pnpm typecheck
After build, load .output/chrome-mv3
in Chrome/Edge via Load unpacked. For Firefox, load the Firefox output folder.
A clean three-layer extension — content script, background worker, and popup — with no external servers in the loop.
┌─────────────────┐ sendMessage ┌─────────────────────────┐ ┌─────────────────────┐
│ Content Script │ ───────────────→ │ Background Service │ ──→│ GitHub GraphQL API │
│ (DOM / UI) │ │ Worker │ │ api.github.com │
│ │ ←─────────────── │ • PAT storage │ │ │
│ • Shadow DOM │ queueStateUpd │ • Sequential queue │ │ │
│ • Row observer │ │ • Rate limit backoff │ │ │
└─────────────────┘ └─────────────────────────┘ └─────────────────────┘
↑
│ WXT Storage API
↓
┌─────────────────┐
│ Extension │
│ Popup │
│ • PAT config │
└─────────────────┘
GitHub will 403-ban your PAT if you fire parallel GraphQL mutations. All operations must run
sequentially with sleep(1000)
between writes.
All GitHub API calls must go through sendMessage to the Background Service
Worker. Never fire fetch to
api.github.com from a content script.
GitHub's CSS class names are generated and change frequently. Always anchor injected UI to stable
data-testid attributes or ARIA
labels.
All injected UI lives in a Shadow DOM container. This guarantees RGP's styles never leak into GitHub's own UI and vice versa.