Skip to content

Scientific Context Notes

TypeScript (strict) Manifest V3 Chrome 116+ Ports & adapters citeproc-js / CSL pdf.js IndexedDB Vitest + Playwright 471 unit + 56 E2E tests Local-first, no backend
Not on the Chrome Web Store yet.
v1.8.1 is the pre-submission build. Until the listing is live, the source and the packaged extension are on GitHub.

A local-first research companion for Chrome: it files sources, keeps every note attached to the exact passage it came from, and turns a pile of highlights into a cited draft.

The Outline screen: passages from four sources each sitting under a heading of the argument, a section named “Counter-arguments: is the heat–mortality link overstated?” marked EMPTY SECTION, and Add section, Copy draft and Download .md controls in the header.

The Outline screen — every highlight given a place in the argument. An empty section keeps flagging itself rather than staying quiet.

The Problem It Solves

I used to print. Reorganising sources and marking the parts that mattered meant a stack of paper, a highlighter and a wall of yellow sticky notes — that was the reliable way to do it, and it did not survive contact with a second reading.

Doing the same work on screen was not obviously better. The tool collected well and delivered nothing: a session ended with notes in a dashboard while the deliverable was an essay in a word processor, and the bridge between the two was a copy button, pressed once per citation. Version 1.8.0 closes that gap — give each highlight a place in the argument, arrange the sections, and export the whole draft to the clipboard or as a Markdown file.

What It Does

  • Files web pages and PDFs into a research project, each source carrying a workflow status from to read through to used in output
  • Anchors every note to the passage it came from, so a highlight re-finds its sentence after a reload — and after the page changes underneath it
  • Reads PDFs in a bundled viewer with text highlights and drag-a-rectangle region anchors
  • Generates real CSL citations through citeproc — APA, Harvard, Vancouver, MLA and Chicago — with a rule editor that previews changes through the live engine
  • Turns the outline into a finished draft: one clipboard copy into Word, or a Markdown file, references included

The Finding That Shaped the Architecture

A citation is a property of the document, not of the source. “How do I cite Nowak” has no answer without “what else is in this essay”. That sentence sounds like theory until you try to build the export, at which point it decides the design.

Three consequences, each established by probing the real citation engine rather than by reasoning about it:

  • Formatting one source at a time renders one citation cluster, so under a numbered style such as Vancouver every source comes out as (1).
  • The engine disambiguates retroactively. Format a citation without the ones that follow it, and the first “(Nowak 2016)” never becomes “(Nowak 2016a)” even though a later one does — the same source cited two different ways in one document.
  • A reference list must receive its entries in first-citation order, or a numbered style’s list disagrees with the numbers in the text.

So the export resolves every citation of a draft in a single engine pass, and the reference list holds only what was actually cited, in the order it was first cited. A passage whose source has no bibliographic record still appears in the draft, marked as incomplete, rather than taking the whole export down with it.

Local-First, and What That Costs

Everything lives in the browser’s IndexedDB. There is no backend, no account, no telemetry and no remote code — Chrome’s Manifest V3 forbids loading code at runtime, so the citation engine, the PDF reader and the fonts all ship inside the extension.

The cost is worth stating plainly, because stating it is the point. Collaboration travels as an encrypted file rather than through a server, and roles are therefore advisory: every collaborator holds a full copy of the project, so nothing can enforce who may do what. The product says so in those words rather than implying a permission system it does not have. Real-time presence is in the same category — it needs a live channel between clients, so the interface shows it as unavailable instead of pretending.

Permissions, Treated as a Design Problem

Reading page text is what lets a highlight re-find its sentence a month later, and most extensions in this category ask for every site at install. This one holds no standing access to any site: broad host access is declared as optional and requested at runtime, on a user gesture, revocable per site or wholesale from Chrome’s own settings.

Two grants share that declaration, and they differ. Annotating a given site asks for that one origin. The side panel’s “Allow reading pages” button asks for all sites in a single prompt — it has to, because activeTab covers only the tab where the toolbar icon was clicked and expires on navigation. Describing both accurately took a release of its own: v1.8.1 corrected the listing and the docs, which had flattened the two into “one origin at a time”. The code was right; the words were wrong.

One Measured Fix

Typing a note made the panel jump and drop keystrokes. Every autosave broadcast “data changed”, and the panel — which had just made that change itself — re-read everything and repainted: measured on a live article, one saved note caused 13 DOM rebuilds, replacing the textarea under the reader’s hands.

Three changes fixed it: a request now carries the id of the surface that made it so a surface ignores its own writes, a repaint is deferred while the caret is in a note, and the list rebuilds only when something visible has actually changed. Re-measured on the same article: 0 rebuilds, 0 lost characters.

Built With

  • Chrome extension, Manifest V3, minimum Chrome 116 — Chromium browsers only
  • TypeScript under strict, plus exactOptionalPropertyTypes and noUncheckedIndexedAccess
  • Ports and adapters: a domain core with no chrome.* and no storage dependency, reached through typed messages and unit-testable in Node
  • 471 unit tests and 56 end-to-end tests — Vitest, and Playwright driving a real headed Chromium with the extension loaded. CI runs typecheck, lint, format check, units and build, with E2E as a separate job
  • Real CSL citations through citeproc-js: APA 7th, Harvard (Cite Them Right 11th and Solent University), Vancouver, MLA 9th, and Chicago 18th in both author–date and notes forms
  • A bundled pdf.js reader; region anchors are stored as fractions of the page box, so they survive zoom, reload and a different screen
  • Web-page anchoring by W3C selectors — text quote, then text position, then a coarse CSS fallback
  • Portable project snapshots, optionally encrypted with AES-GCM; an import previews exactly what it would change before writing anything
  • The extension’s own code is MIT; it bundles citeproc-js (CPAL-1.0), pdf.js (Apache-2.0) and CSL styles (CC BY-SA 3.0)

What’s Next — Vote on the Roadmap

These are the improvements on the table. Vote for the ones you want first — one vote per idea per day, no sign-up. Missing something? Suggest it below and it can end up on this list.

Export the draft straight to .docx

  • Today a draft goes to the clipboard as formatted HTML, or downloads as Markdown
  • A real .docx would carry styles and footnote citations into Word untouched
  • Same single-pass citation resolution — only the container changes

More bundled citation styles

  • Seven ship today: APA, Harvard (Cite Them Right and Solent), Vancouver, MLA and Chicago × 2
  • IEEE, OSCOLA and other university house styles are the most likely next ones
  • Any .csl file can already be imported — a bundled style just needs no setup

Import from and export to Zotero / BibTeX

  • Bring an existing library in instead of re-filing every source by hand
  • Hand a finished project’s references back out in a format other tools read

Live presence and real-time sync

  • See who else is in the project, and whose note you are reading
  • Needs a live channel between clients, so it needs a backend — today collaboration is an encrypted file and roles are advisory
  • Votes here are a vote for building that backend at all

Suggest a Feature or Report a Problem

Both go straight to me. No account, no ticket system — an email address is optional, and only needed if you want an answer.