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 (GitHub for now; Gitea and Forgejo soon).

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.
  • One branch, quibble-screenshots, and only if screenshots are used. 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 work

TrackerTested against
GitHub.comLive
Gitea1.27.3
Forgejo12.0.4
GitHub Enterprise ServerNot yet tested

Tested against a running instance of each, not read from documentation. Screenshots work on GitHub; on Gitea and Forgejo a note still files, without the image. Built from quibble 1.15.0.

See it before you wire it up

The live demo runs quibble itself in your browser, with nothing to install.

Try it live