bibbot: reusing your library's press access to read German news sites
BibBot is a browser extension that removes the paywall on German online news sites using your library account's access to press databases.
At a glance
- What is it?
- BibBot is a TypeScript browser extension that uses your own library or university credentials to reach the press databases that publisher already grants you access to, and then extracts the article for you to read on the publisher's own page. It suits German readers whose subscription does not cover a given title but whose local library does, and the honest way to evaluate it is that the extension is a session broker rather than a paywall breaker, which moves the legal question to the terms of your library agreement and the publisher's.
- Who is it for?
- Adopt BibBot if your library or university subscribes to German press titles that you want to read and your institutional access is the legitimate route to them.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four entry points and a data model that separates access from content
BibBot is a browser extension that removes the paywall on German online news sites using your library account's access to press databases. The project description says it plainly, and the repository structure shows how the work is divided.
The extension has four different entry points. The content script in `src/content.ts` runs on the news article page and communicates with the background script. The background script in `src/background.ts` opens new tabs, navigates them around and scrapes the content. The options page in `src/options.ts` is the extension's settings page. And the popup in `popup/` is opened when the extension icon in the toolbar is clicked.
Then there are the three data files, and the split between them is the part that explains the whole design:
`src/providers.ts` contains libraries that you authenticate against and that grant access. `src/sources.ts` contains databases that you can get access to through providers. `src/sites.ts` contains news sites, how to extract their meta data and which source could provide access.
So the model is a three-layer chain. A site is a page you want to read. A source is a database that could supply it. A provider is the library that gives you access to that database. The extension authenticates you against the provider, uses the source to obtain the article, and then scrapes the content out of the tab it opened. The details of how to construct any of these entities are in `src/types.ts`.
User data like credentials and the chosen provider is stored via `browser.storage.sync`, which is the extension storage that syncs across the browser's signed-in profile rather than staying local to one machine.
The project is GPL-3.0, written in TypeScript, with the last push on 2026-04-13 and releases v0.40.8 from 2025-10-27 and v0.40.7 and v0.40.6 from 2025-08-11.
Building the extension with rollup
The build is a rollup setup with a watch mode, and the README gives the two commands.
npm install
# Run this during development
npm startThe package manifest shows what that means in practice. The `start` script is `rollup --bundleConfigAsCjs -c -w`, so the development mode is a rollup watch on the config, and `build` is the same without the watch flag. The `rollup.config.js` at the repository root and the `babel.config.js` next to it are the build configuration, and the rollup plugins in the dev dependencies are the standard set, commonjs, node-resolve and typescript.
The linting and typing are separated into two scripts, `lint` running eslint over `src` and `tests`, and `check-types` running `tsc --noemit`. The eslint setup is a config-per-plugin affair rather than a flat one, with the standard config, the import, node and promise plugins, the typescript-eslint plugin and parser, and eslint-config-prettier alongside prettier itself so the two do not fight.
There are husky hooks, installed through the `prepare` script, and a `.husky/` directory plus a `.prettierrc.json` and an `.eslintrc.json` at the root. The `dist.sh` script and `generate_icons.sh` sit alongside them, and the `manifest.json` at the root is the extension manifest, with an `updates.json` and an `index.html`.
The result of a build is a `dist/` directory, and it is committed to the repository, which is what lets the release workflow produce something installable without a build step at install time.
The type story is worth a note. The dev dependencies include `@types/chrome` and `@types/webextension-polyfill` alongside the polyfill itself, so the code is written against the WebExtension API with a compatibility shim for the older Chrome extension API, and it is TypeScript throughout with the source in `src/` and `popup/` and `options/` as separate directories.
Playwright tests that need the build to exist first
The test setup is worth reading because of one detail that trips people up, and because the shape of the test data says something about the project.
The test setup for sites uses Playwright and can be run with:
# install dependencies
npm ci
# Run linting and type checking
npm run lint
npm run check-types
# Always run build before tests, as test uses build files!
npm run build
# Run tests
npm run test
# Run tests with actual browser window for one domain
npm run test -- --headed -g "zeit.de"The comment is the point. Always run build before tests, as test uses build files. The tests exercise the built extension rather than the source, so a green test run against a stale `dist/` tells you nothing.
The package scripts split the suite into two Playwright invocations. `test-sites` runs `tests/sites.spec.ts` with a list reporter, and `test-extension` runs `tests/extension.spec.ts` with a dot reporter and in headed mode, so the extension itself is driven in a visible browser window. The full `test` script runs both.
Then there is the test data convention, which is how new sites get covered:
// ...
'www.example.com': {
examples: [
{
url: 'http://example.com/article.html',
selectors: {
query: 'The string resulting from query selector'
}
}
],
// optional setup async function
testSetup: async (page) => {
// page is playwright page
// use this for initial page setup
},
// ...So each site entry carries example URLs and the selectors used to extract content, plus an optional async setup function that receives the Playwright page for cases needing initial state. That is a data-driven test suite, where adding a new publisher means adding data rather than writing a test.
The playwright.config.ts at the root and the `tests/` directory complete the picture, and the CI badge in the README points at a workflow that runs this suite.
Releases, signing and the store submission pipeline
The release process is three steps, and the third one is the interesting part.
1. Run `npm version <major|minor|patch>` 2. `git push --tags origin main` 3. GitHub release Action will build, test, create release, sign Firefox extension, submit to Chrome Web Store and update website.
Step one is not quite the stock npm behaviour. The `version` script in the package manifest rewrites the version inside manifest.json using `gsed` and reads the new version out of package.json with `jq`, so the extension manifest stays in step with the package version automatically. The manifest is then staged, so it goes into the commit that `npm version` creates.
Step three is a full release pipeline in one workflow. The GitHub action builds, runs the tests, creates the release, signs the Firefox extension, submits to the Chrome Web Store and updates the website. The website update is a good clue about the project's shape: the official site at stefanw.github.io/bibbot is generated from the same repository, and there is an `assets/` directory, an `icons/` directory and a `generate_icons.sh` script, so the icon set for the extension and for the site is maintained in one place.
The Firefox and Chrome difference is not an accident of wording. Firefox add-ons can be signed with a key the developer holds, and the action does that signing. The Chrome Web Store submission is a different mechanism entirely, involving a review process and a store account, so the same repository has to satisfy two distribution systems with one release, and the automation exists to make that a single push.
There is also a `privacy.md` in the repository root, which matters more for this project than for most. The extension stores library credentials in the browser, and a page that explains what is stored and where is the first thing a reviewer or a cautious user would look for.
What this tool is, and where the ethical line actually sits
The comparison worth making is with the other two ways to read a paywalled German news article, because the legal position differs sharply between them.
The first is a conventional subscription, which is what the publisher offers and what the reader pays for. The second is a pirate site that republishes the article without any access to the publisher's systems. BibBot is neither of those, and understanding why is the point of evaluating it.
The extension does not obtain the article from the publisher's paywall infrastructure. It authenticates you against your library's press database, using the credentials your institution gave you, and asks that database for the article, exactly as you would if you opened the database's website yourself. The content it then shows you comes from the database, through a tab the extension opened and scraped. In other words, the entitlement being exercised is the one your library already granted you, and the extension is a session broker that automates the sequence of steps a person would do by hand.
That distinction is real but it is not a complete answer to the question, and anyone adopting the extension should know two things.
The first is that your library agreement and the publisher's licence both have terms about bulk and automated retrieval. A person reading one article through a proxy and an account retrieving hundreds may be treated differently by the counterparty, and the extension is where that difference becomes visible in a log. The repository does not discuss this, and neither the licence file nor the extension description resolves it, so it is a question to ask your library rather than one this project can answer.
The second is that the source data model makes the coverage uneven. A site is only readable if some source in `src/sources.ts` carries it and some provider in `src/providers.ts` grants access to that source. German local newspapers and the bigger national titles are covered unevenly by press databases, and the ones that are not covered simply do not work, which limits the tool in a way that a blanket paywall remover would not.
The practical summary is that BibBot is best understood as an access broker for institutional subscriptions, useful for a reader whose library carries a title they want, and dependent on the good behaviour of libraries and publishers for its acceptability.
Editorial conclusion
Adopt BibBot if your library or university subscribes to German press titles that you want to read and your institutional access is the legitimate route to them. Do not adopt it as a general paywall remover, because it only helps where a provider grants you access and the extension is a session broker rather than a way to read content you are not entitled to, and check first what your library agreement permits, since automated retrieval against a press database is the part that publishers and libraries tend to have opinions about.
Frequently asked questions
What is BibBot?
It is a browser extension that removes the paywall on German online news sites using your library account's access to press databases. It authenticates against the provider, asks the source database for the article and scrapes the content from a tab it opened.
How is the BibBot extension structured?
Four entry points: a content script in src/content.ts that runs on the article page, a background script in src/background.ts that opens tabs and scrapes, an options page in src/options.ts and a popup in popup/. The data lives in src/providers.ts for libraries, src/sources.ts for databases and src/sites.ts for news sites, with types in src/types.ts.
How do I build and test BibBot?
Run npm install and npm start for a rollup watch build. For tests, use npm ci, npm run lint, npm run check-types, then npm run build before npm run test, because the tests exercise the built extension files. A single domain can be run with npm run test -- --headed -g "zeit.de".
How are BibBot releases published?
Run npm version with a major, minor or patch argument, then git push --tags origin main. A GitHub release action then builds, tests, creates the release, signs the Firefox extension, submits to the Chrome Web Store and updates the website.
Is BibBot still being maintained?
The repository is not archived and the last push was on 2026-04-13. The listed releases are v0.40.8 from 2025-10-27 and v0.40.7 and v0.40.6 from 2025-08-11, and the project is GPL-3.0 licensed.
Official sources
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.
[](https://hysenlabs.com/projects/stefanw-bibbot)Was this useful?