v0.1.4 · Manifest V3 · No backend required

GitHub Projects,
bulk-edited.

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.

11+ Bulk actions
3 Browsers supported
100% Local & private
MV3 Manifest version

GitHub Projects is powerful.
Managing it at scale isn't.

Refined GitHub Projects — live demo

Refined GitHub Projects fixes the gaps that slow down every sprint planning session.

📋

One field at a time, forever

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.

🔁

GitHub's duplicate strips everything

The built-in duplicate copies only the title. Every assignee, label, status, and project field has to be re-applied manually — every single time.

🏃

Ending a sprint is a chore

Moving incomplete items to the next iteration requires opening each issue individually, changing the sprint field, and hoping you didn't miss any.

🔒

No visibility into background ops

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.

Everything your project board
was always missing.

01 / BULK ACTIONS

Select many. Edit once.

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.

Bulk Edit Fields Close Issues Reopen Issues Deep Duplicate Pin / Unpin Transfer Export CSV Delete
Bulk Actions Bar showing all available operations
02 / BULK EDIT WIZARD

Pick fields. Set values. Apply to all.

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.

Step 1: Select Fields Step 2: Set Values Step 3: Review & Apply
Bulk Edit Wizard 3-step flow
03 / DEEP DUPLICATE

Clone issues like a real copy machine.

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.

All project fields preserved Assignees & labels copied Edit before duplicating
Deep Duplicate modal
04 / SPRINT MANAGEMENT

End sprint. Move items. Instantly.

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-click sprint end Auto-move incomplete items Live queue tracker Configurable condition
Sprint Management panel and End Sprint modal

Everything GitHub Projects
should have shipped.

One extension. Eleven features. Zero extra tabs. One token stays local.

Full list of bulk actions available in Refined GitHub Projects
✏️

Edit Fields

Bulk-update Status, Priority, Sprint, Size, Estimate, Assignees, Labels, and custom fields

⌘⇧E
📝

Rename Titles

Update issue or PR titles across multiple items at once

⌘⇧R

Reorder Items

Reposition selected items within your project board

⌘⇧J

Close Issues

Mark as Completed or Not Planned. Sweep a whole sprint in one action.

⌘⇧X

Reopen Issues

Restore closed items back to open. Only affects actually-closed issues.

⌘⇧O
🔒

Lock Conversations

Lock with reason: off-topic, too heated, resolved, or spam

⌘⇧L
📌

Pin / Unpin Issues

Promote or demote important issues at the repository level (max 3)

⌘⇧F

Transfer Issues

Move issues to another repository with full history intact

⌘⇧M

Export to CSV

Download selected items with all fields, assignees, labels, and custom properties

⌘⇧V

Deep Duplicate

Clone any item with all fields, assignees, labels, body, and sub-issue relationships

🗑

Delete Items

Permanently remove items from your project. Requires admin access.

⌘⇧⌫
🏃

End Sprint

One click moves all incomplete items to the next iteration automatically

Up and running
in under two minutes.

1

Download the latest release

Go to the Releases page and download the browser build package (not the source archive). Extract it on your machine.

2

Open your browser's extension page

Chrome / Edge: chrome://extensions
Firefox: about:debugging#/runtime/this-firefox

3

Load unpacked extension

Chrome / Edge: enable Developer mode, click Load unpacked, select the extracted folder.
Firefox: click Load Temporary Add-on, select the manifest file.

4

Add your GitHub PAT

Click the extension icon, paste your token, and click Validate and save. All features unlock automatically — one token for everything.

Tested browsers
✅ Arc (Chromium) ✅ Microsoft Edge ✅ Zen (Firefox)

🔑 Required PAT scopes

repo Read/write issues, labels, assignees
read:org Read org membership for assignee search
project Read/write GitHub Projects V2 fields
🔒 Your token is stored in browser extension storage and never sent to any server. All API calls go directly from your browser to api.github.com.
Generate a PAT

GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic)

Generate token →

Build it yourself.

Node.js 18+ and pnpm required.

bash
# 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.

How it works.

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   │
└─────────────────┘

⛔ Never use Promise.all() for mutations

GitHub will 403-ban your PAT if you fire parallel GraphQL mutations. All operations must run sequentially with sleep(1000) between writes.

⛔ Never call the API from Content Scripts

All GitHub API calls must go through sendMessage to the Background Service Worker. Never fire fetch to api.github.com from a content script.

✅ Anchor to data-testid / ARIA labels

GitHub's CSS class names are generated and change frequently. Always anchor injected UI to stable data-testid attributes or ARIA labels.

✅ Shadow DOM isolation

All injected UI lives in a Shadow DOM container. This guarantees RGP's styles never leak into GitHub's own UI and vice versa.

What's shipped, what's next.

Bulk update fields — Status, Assignee, Sprint, Priority, Labels, custom fields
Bulk close / reopen issues
Bulk lock / pin / unpin / transfer / delete
Bulk rename titles & reorder items
Export selected items to CSV
Deep duplicate with all fields and sub-issues
Sprint management — end sprint with auto-assignment
Task completion tracker in sprint group headers
Live queue tracker with real-time progress and rate-limit backoff
Chrome Web Store release
Firefox Add-ons release
Safari support