Free tools for legal scholars, professors, research assistants, and journal editors. Archive citations, audit footnotes, clean redline identities — entirely in your browser. Built at NYU Law.
Save it once, archived forever.
An open-source Zotero plugin that automatically generates perma.cc archive links in the background as you build your research library — before the URL ever breaks.
Batch-archive every URL in your manuscript.
Drag in your .docx, select the URLs you want archived, and get back a Bluebook Rule 18.2-compliant document — with perma.cc links inserted directly into footnotes. Clean copy or Track Changes redline.
Find citation logic errors before your editor does.
Automatically audits supra, Id., signal parentheticals, hereinafter, and pincite patterns across all footnotes in your Word document. No installation. No uploads.
Standardize visible review identities before circulation.
Upload one or more .docx files, review the names Word found in comments and tracked changes, and unify internal editor or assistant identities into a clean outward-facing label before sharing.
The Zotero Perma Archiver is a native Zotero plugin built on the Zotero JavaScript plugin API. It hooks into your library events and calls the perma.cc REST API in the background as you save items — running entirely inside your Zotero desktop app, no browser required.
PermaDrop and SupraDrop parse .docx files using JSZip to extract raw XML, then run all citation logic entirely in your browser — no frameworks, no telemetry, no dependency on external services beyond perma.cc.
Redline Name Cleaner uses the same fully client-side approach to inspect Word revision metadata, rewrite reviewer names, and export cleaned copies without uploading drafts or exposing internal identities.
Every tool is publicly available on GitHub under the AGPL v3 license. You can read exactly what runs on your machine.
// JSZip parses the .docx (a ZIP archive)
const zip = await JSZip.loadAsync(file);
const xml = await zip
.file('word/footnotes.xml')
.async('string');
// Parse footnote XML nodes in-browser
const parser = new DOMParser();
const doc = parser.parseFromString(
xml, 'text/xml'
);
const footnotes = doc
.querySelectorAll('w\\:footnote');
// No data leaves the browser
footnotes.forEach(fn => {
validateSupraChain(fn, index);
validateIdUsage(fn, prev);
validateSignals(fn);
});