How it works
Three pieces, all yours: a script tag in your pages, a Python package inside your app, and the issue tracker you already use. There's no quibble service in between.
Where a note goes
Someone clicks the button and writes a sentence. The widget sends it, with the page context, to an endpoint mounted in your own app. Your app files it as an issue using one service token that only your app holds.
That's the whole path. quibble has no telemetry and makes no call home, and the widget's script is served by your app from your own domain, so it adds nothing to your content security policy.
- Browser
- Your app
- Your tracker
The three pieces
The widget
One script tag. Vanilla JavaScript with no dependencies and no build step. It draws the button and panel inside a shadow root, so your styles can't reach it and it adds none to your page.
The adapter
A Python package with no dependencies of its own. Mount it on FastAPI, Django, Flask, Starlette or Litestar in a couple of lines. Others can integrate using a documented schema.
Your tracker
Each note becomes an issue carrying a marker label, so feedback is easy to filter from the rest of your work. There's no database: the tracker is the datastore.
What arrives with every note
Always
What they wrote, the page they were on, its title, where they came from, their screen size, browser, language and time zone.
Who sent it
Their name from the sign-in you already have. Without one, they can type it, and the issue says it's self-declared.
When something broke
The last five JavaScript errors the page threw, folded away under Diagnostics until you want them.
When they choose
The element they pointed at. A screenshot, with any region you mark private blanked out.
Additional context you need
Console output, failed network requests and any fields your app wants to add. Off until you turn them on.
What quibble writes to your repository
Worth knowing before you point it at a repository that matters. This is the complete list:
- Issues, each carrying the marker label.
- Labels: the marker, and
P1,P2,P3, created only if missing. Never anything else: a tag your tracker doesn't have is dropped, not created. - On GitHub only, one branch,
quibble-screenshots, and only if screenshots are used; other trackers attach the image to the issue. It never touches your default branch.
No comments, no closing, and no edits to anything quibble didn't create.
Everything else it does
Point at it
“This button, here.” People click the element that's wrong, and its selector and text go into the issue.
Private stays private
Mark a region private and its text is never captured and it's blanked out of screenshots.
Your styles can't break it
The widget lives in a shadow root. Your CSS can't reach it, and it adds none to your page.
One button, many repositories
Route notes by page or let people pick. Discover every repository in an org, and mix GitHub with a self-hosted Gitea.
A review page
Every quibble in one list, filtered by open or closed, with close and reopen one click away.
Tags you choose
Offer all your labels, an allowlist, or everything except a blocklist.
Rate-limited writes
Each signed-in sender gets a budget, so one enthusiastic user can't flood your tracker.
An off switch
Set one variable and your app mounts no quibble routes at all.
quibble doctor
Checks a deployment's token, repositories and labels, and reports what's wrong without printing a secret.
quibble demo
Runs a sample app with every feature reachable, offline, with no token.
A test kit
In-memory fakes of each supported tracker ship with quibble, so your own tests run with no network.
Which trackers and languages work
Trackers
| Tracker | Status |
|---|---|
| GitHub | Tested live |
| Gitea | Tested on 1.27.3 |
| Forgejo | Tested on 12.0.4 |
| GitLab | Tested on 19.4.1 CE |
| GitHub Enterprise Server | Not yet tested |
| Jira Data Center / Server | Roadmap |
| Azure DevOps | Under consideration |
| Redmine | Under consideration |
| Bitbucket Data Center | Under consideration |
Every tested version is one we ran quibble against, not one we read about. GitHub Enterprise Server ships as a licensed appliance we can't stand up, so it stays marked untested until someone runs it. Supported rows are generated from quibble 1.17.0 itself; roadmap rows are plans, not promises. Screenshots work on every supported tracker.
See it before you wire it up
The live demo runs quibble itself in your browser, with nothing to install.