quibble.fyi
Early access

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.

quibble
  1. Browser
  2. Your app
  3. 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

TrackerStatus
GitHubTested live
GiteaTested on 1.27.3
ForgejoTested on 12.0.4
GitLabTested on 19.4.1 CE
GitHub Enterprise ServerNot yet tested
Jira Data Center / ServerRoadmap
Azure DevOpsUnder consideration
RedmineUnder consideration
Bitbucket Data CenterUnder consideration

Languages

LanguageStatus
PythonSupported
Any other stack
By implementing quibble's documented schema.
Supported
Apps in other languages, through a small sidecar service rather than a port per language.
Roadmap

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.

Try it live