Open-source project
hypothesis/browser-extension avatar
hypothesis/browser-extension

Hypothesis browser extension: annotating any web page from inside the browser

The Hypothesis browser extensions.

556 stars142 forksJavaScriptBSD-2-Clause

At a glance

What is it?
The Hypothesis browser extension wraps the Hypothesis client so a Chrome user can comment on any page while browsing, with Firefox still in development. It suits a reader, writer or teacher who wants to comment on the live document rather than on a screenshot.
Who is it for?
The Hypothesis browser extension is worth installing if you annotate documents for a living, because annotating the live page is materially better than annotating a PDF rendering of it, because the text stays selectable and the anchor points to the real document, and because the extension is a thin wrapper around the client, so the annotation model is the same one the service uses everywhere else.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the extension does, and which browsers exist

The Hypothesis browser extensions allow you to annotate web documents using your Hypothesis account, and the package description puts it as: annotate with anyone, anywhere.

Hypothesis is a service for collaborative annotation, and the extension is the part of it that runs in the page you are reading. The interesting property is that it annotates the live document rather than a document you have uploaded, so the text you select is the text on the page, the highlight sits over the real element, and the anchor survives because the document itself is still there.

The browser table in the documentation is short and matters. Chrome is marked as now available, with a link to the Chrome Web Store listing, and Firefox is marked as in development, with the link pointing nowhere. The images of both browser logos are in the repository, but only one of them has something behind it.

That is the first thing to check before anything else, because the extension's usefulness does not survive a browser that does not run it, and there is no Firefox build to fall back on. For a project that has existed for years, the Firefox version being unfinished is a fact worth weighing, since a service that most people use from a Firefox install cannot be used from a Firefox install.

The project is BSD-2-Clause licensed, the primary language is JavaScript, the default branch is main, and the last push to the repository was on 2026-10-19. There are no GitHub releases, which is consistent with a project whose artefacts are browser store entries rather than downloadable packages.

Building it locally, and loading it as an unpacked extension

The development instructions are short enough to follow exactly, and the important detail is that the extension is not self-contained.

The code for the extensions is in the src/ directory, and it is built into a browser extension by running:

bash
make build

Once that is done you can load the build/ directory as an unpacked extension, which is the standard way to run an extension that is not from a store. The Makefile shows what that involves: the build target depends on a node_modules marker file and on an extension target, which in turn builds a bundle with Rollup, a manifest, and the client assets. The manifest and the bundled client are separate outputs, and the client is where the bulk of the application lives.

The test suite runs the same way:

bash
make test

And the Makefile also offers the rest of the usual targets, with help listing them: a dev target that watches for changes and rebuilds, lint, checkformatting, format, a sure target that makes sure the formatter, linter and tests all pass, and a clean target that removes the development artefacts, the cached files and the dependencies.

The build settings come from a JSON file selected by a variable at the top of the Makefile, SETTINGS_FILE pointing at settings/chrome-dev.json, and a tool script generates build/settings.json from it with a checksum comparison so the output is only updated when it actually changes. That is the mechanism for switching between the Chrome and Firefox variants, and it is a small piece of engineering that saves a rebuild for nothing.

The extension sources themselves are listed as a variable in the Makefile, EXTENSION_SRC covering pdfjs, help, images and options, and the extension target produces the bundle, the manifest, the client build, the client HTML entry points for the app, the notebook and the profile, an unload script, and the pdfjs input.

The extension is a wrapper, and that is the key architectural fact

The documentation is candid about what the repository contains. The browser extensions are for the most part just a wrapper around the Hypothesis client. Depending on what you are interested in working on, you may need to check out the client repository too.

That has a direct practical consequence for a developer. Once you have checked out and built the Hypothesis client, you can use it by running the following command in the browser-extension repository:

bash
yarn link ../client

where ../client is the path to your Hypothesis client checkout. After that a call to make build will use the built client from the client repository. The documentation tells you to consult the client's own documentation for how to build the client in a development environment.

So the extension is a thin shell around a much larger application, and a change to the annotation behaviour is usually a change to the client. The repository dependencies confirm the scale of that. The hypothesis package is on version 1.1769.0, matching the extension's own version, and there are the shared Hypothesis build and testing packages, @hypothesis/frontend-build and @hypothesis/frontend-testing, which suggests a common toolchain across several front-end repositories rather than one built for this project alone.

The unlinking instruction is the counterpart:

bash
yarn unlink hypothesis

run in the browser extension directory, with a link to the yarn uninstall documentation. The existence of a documented unlink step is a small thing that says the project expects people to switch between the published client and a local build, which is what happens to everyone who works on this code for more than an afternoon.

For an end user, all of this is invisible. The extension talks to the service, the account is the same account, and the annotations are the same annotations.

The toolchain, and what the package manifest reveals

The package manifest describes a project with a serious build and test setup, and the versions are current.

The package is hypothesis-browser-extension at version 1.1769.0, marked private and of type module, with the BSD-2-Clause licence and the homepage at hypothes.is. The browser support is declared as a browserslist entry of chrome 85, firefox 75, which is a deliberate floor rather than a default, and it tells you the code is transpiled to a baseline that both browsers can run.

The build is Rollup with a set of plugins, one for each job, including alias, babel, commonjs, json, multi-entry, node-resolve and replace. The multi-entry plugin is what produces the several client entry points, and the replace plugin is how the build injects the settings file. Babel itself is present with the preset-env and preset-typescript packages, and the babel-plugin-mockable-imports and babel-plugin-istanbul packages point at a testing strategy that mocks module imports and measures coverage through the same transform.

The test stack is Vitest 4 with the browser mode, @vitest/browser and @vitest/browser-playwright, driven by Playwright at version 1.57. That is a real browser test environment rather than a DOM emulation, which is the right call for an extension whose entire behaviour depends on injecting into a real page, and it is expensive enough that the choice is deliberate.

The publishing side is also handled. The chrome-webstore-upload-cli package is a dependency, so the store upload is scripted, and web-ext at 9.2.0 is the Mozilla equivalent for the extension that is not finished yet. Gulp 5 is there as the task runner the test script uses, and mustache is the template engine, which is how the client HTML is generated.

The remaining tooling is the usual set for a shared monorepo-style front end: ESLint 9 with the shared eslint-config-hypothesis configuration, Prettier 3.8.4, TypeScript 5.9 with typescript-eslint, sinon and chai for unit level tests, codecov for coverage reporting, and a .yarnrc.yml with a yarn.lock, which places the project in the Yarn 2 and later line rather than Yarn 1.

Where the Hypothesis browser extension is the wrong tool

The first limit is the browser gap, and it is the one that decides the question for a lot of people. Chrome is available and Firefox is in development, and for a service whose user base includes a large share of Firefox users, the extension being Chrome-only for the length of time it has been is the practical problem with the project.

The second is what it does not do. The extension annotates web documents. It is not a tool for marking up a PDF file you have locally, which is the workflow that a large share of academic annotation actually happens in, and the presence of a pdfjs source directory in the build suggests PDF handling exists in some form, but the project documentation describes the extension as being for web documents and says nothing about local files.

The third is the account requirement. The extensions let you annotate using your Hypothesis account, so there is no offline mode and no anonymous mode. A reader who wants to highlight something for themselves and never share it is being asked to sign up for a service to do it, and the privacy story of a hosted annotation service is a different question from the privacy story of a local tool.

The fourth is the coupling for contributors, which is the practical version of the wrapper point. Working on the extension properly means building two repositories, the client and the extension, and keeping them linked with yarn link, and a contributor who wants to change behaviour has to understand which of the two they are actually changing. For a project with a shared build and test package set, that is a managed kind of coupling rather than a wild one, but it is still two checkouts.

And the fifth is the release channel. There are no GitHub releases and the artefact is a store listing, so the version of the extension a user gets is whatever Chrome Web Store decides to serve, and the versioning is tied to the client version, with the package and the client dependency both sitting on the 1.1769.0 line. A team that wants to pin an extension version for a managed environment has a store artefact rather than a package to lock, and the version numbers move in step with a much larger client's release cadence.

Editorial conclusion

The Hypothesis browser extension is worth installing if you annotate documents for a living, because annotating the live page is materially better than annotating a PDF rendering of it, because the text stays selectable and the anchor points to the real document, and because the extension is a thin wrapper around the client, so the annotation model is the same one the service uses everywhere else. It is the wrong tool if you work primarily in PDF workflows, and it is the wrong tool on Firefox today. Before you install it, check three things: which browser you have, because the Chrome extension is marked as now available and the Firefox one as in development, so a Firefox user is waiting on a build that does not exist yet; that the package version tracks the client, with the package at 1.1769.0 and the hypothesis client dependency on the same 1.1769.0 line, so a mismatch between extension and client is a version skew you can avoid; and that you understand what you are agreeing to, since the project is released under the 2-Clause BSD License with some third-party components included under their own licences, and the full set of licence information is in the included LICENSE file.

Frequently asked questions

Which browsers does the Hypothesis browser extension support?

The Chrome extension is listed as now available and can be installed from the Chrome Web Store, while the Firefox extension is listed as in development. The package manifest declares a browserslist of chrome 85 and firefox 75, so the code itself targets both, but only the Chrome build is published.

How do I build the Hypothesis browser extension locally?

Run make build, which compiles the sources in src/ with Rollup and produces a build/ directory you can load in the browser as an unpacked extension. The test suite runs with make test, and the Makefile also provides a dev target that watches and rebuilds, plus lint, format, sure and clean targets.

Do I need the Hypothesis client repository to work on the extension?

Only if you want to work on the behaviour rather than the shell. The extension is for the most part a wrapper around the Hypothesis client, so a developer should check out and build the client repository too, then run yarn link ../client in the browser-extension repository, after which make build uses the locally built client. You unlink it again with yarn unlink hypothesis.

Official sources

  1. hypothesis/browser-extension on GitHub
  2. Issues
  3. License: BSD-2-Clause
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hypothesis-browser-extension.svg)](https://hysenlabs.com/projects/hypothesis-browser-extension)