PubMed
MEDLINE, PubMed Central and NCBI Bookshelf. PubMed's syntax and filters, MeSH headings, spelling suggestions.
Any search, as a map.
Broccoli is a GenesisL1 in-house open-source search results clustering engine. It turns the results of any search into a zoomable map of named topics, clustered in your own browser in seconds: eleven sources are built in, from PubMed, arXiv and ClinicalTrials.gov to DataCite and Wikipedia, and any other search plugs in with a few lines. Click a topic and it opens into subtopics of its own, up to six levels deep.
longevity[tiab] AND (aging[tiab] OR ageing[tiab]) · the first 200 records with abstracts · 28 topics found by LingoA search answers a question with thousands of records, ranked one after another. The list tells you what matches. It does not tell you what the field is made of: which questions dominate, which sit at the edges, where two lines of work meet.
Broccoli reads the titles and abstracts, finds the phrases and concepts they share, names every group in the records' own words and lays the groups out by size. Before you open a single record, you see the landscape.
Any of eleven sources, in its own syntax, or a search of your own.
Up to 2,000 records, straight from the source's API and within its rate limits.
Lingo, STC or bisecting k-means, in a Web Worker on your own device.
Zoom through the topics, read the records, export RIS, BibTeX, CSV or JSON.
Each source is a small adapter that turns one API's answers into the same record: title, abstract, authors, venue, identifiers and subject terms. Every one of them answers requests from web pages, so your browser calls it directly.
MEDLINE, PubMed Central and NCBI Bookshelf. PubMed's syntax and filters, MeSH headings, spelling suggestions.
Life-science literature, patents, theses and preprints, with abstracts, MeSH headings and citation counts.
Registered clinical studies: what is tested, in whom, by which sponsor, in which phase, and whether it is recruiting.
bioRxiv, medRxiv, Research Square, SSRN, Preprints.org and more, with the server each preprint is on.
Physics, mathematics, computer science and more. arXiv's own API does not answer web pages, so this tab reads the OpenAlex index of arXiv.
An open index of scholarly works in every field, with abstracts, keywords and citation counts.
Works with Crossref DOIs from every publisher, with the abstracts publishers deposit, ranked by how well they match.
Articles from the vetted open access journals of the Directory of Open Access Journals, in every field and many languages.
Datasets and software with DataCite DOIs, from Zenodo, Dryad, Figshare, institutional repositories and data centres.
High-energy physics, astrophysics, cosmology and gravitation, with collaborations, arXiv links and citation counts.
A general search in eight languages: page titles and the text around each match, with topics labelled in the page's language.
Any search API becomes a tab of its own: a fetchPage function, or an address template and the names of the fields.
What about Google? Its Custom Search JSON API, the usual way to put Google results into a program, is closed to new customers and due to shut down on 1 January 2027, so the open general search here is Wikipedia. A web search API that needs a secret key plugs in through a small proxy of your own.
This is Broccoli itself, running in your browser, with a tab for every source. Pick a source and type a question, or start from one of these searches.
Your searches go from your browser straight to the source you pick. Nothing passes through GenesisL1, no source needs a key or an account, and your settings stay in your browser.
Broccoli knows nothing about medicine or physics: it finds the topics in whatever text a search returns. These are the workflows its sources open, and the last card is everything else.
See what a field is made of before you read it, and which corners a query reaches that you did not mean.
The newest preprints on a subject, sorted by date and read as topics, a week or a month at a time.
What is being tested for a condition, in which phase, by which sponsors, and what is recruiting now.
The datasets and software deposited on a subject, grouped, with their repositories and versions.
High-energy physics and cosmology, with collaborations, arXiv links and the papers cited most.
Articles from vetted open access journals in every field and language, all free to read.
The meanings and neighbours of a term across Wikipedia, in English and seven other languages.
Support tickets, survey answers, interview notes, patents, news, product reviews, internal documents: give it any text records.
The library is a single script of about 420 KB with no dependencies: the three algorithms, the clustering engine and its Web Worker, the search sources, label highlighting and exports for reference managers. A source of your own is an object with a name and a function that fetches one page of results; Broccoli pages through, keeps to the rate limit, retries, and fills in the record.
registerSource and jsonSource: any search API, as a tab of the search page<script src="https://cdn.jsdelivr.net/gh/GenesisL1/Broccoli@v1.5.0/dist/broccoli.js"></script>
<script>
// a built-in source: 'pubmed', 'europepmc', 'clinicaltrials',
// 'preprints', 'arxiv', 'openalex', 'crossref', 'doaj',
// 'datacite', 'inspire' or 'wikipedia'
const res = await Broccoli.searchSource('arxiv', 'graph neural networks', {
limit: 300, sort: 'date', from: 2024,
});
const topics = Broccoli.cluster(Broccoli.toDocuments(res.records), {
preset: 'abstracts', queryHint: res.query,
});
for (const t of topics.clusters) console.log(t.label, t.size);
</script>
Broccoli.registerSource({
id: 'my-index', name: 'My index', pageSize: 100,
async fetchPage(req, page) { // page: { page, size, offset, cursor }
const url = Broccoli.buildUrl('https://search.example.org/api', {
q: req.query, size: page.size, from: page.offset,
});
const json = await req.request.json(url); // rate-limited, retried
return {
total: json.total,
records: json.items.map((it) => ({
id: it.id, title: it.title, abstract: it.summary,
url: it.link, year: it.year, authors: it.authors,
})),
};
},
});
// registered before app.js loads, it gets a tab on the search page
Broccoli.registerSource(Broccoli.jsonSource({
id: 'my-index', name: 'My index',
url: 'https://search.example.org/api?q={query}&size={size}&from={offset}',
results: 'items', // where the list of results is
total: 'total',
fields: {
id: 'id', title: 'title', abstract: 'summary',
url: 'link', year: 'year', authors: 'authors', venue: 'journal',
},
}));
const docs = [
{ title: 'Printer jams after the update', body: '…' },
{ title: 'Refund for a double charge', body: '…' },
// … hundreds more: tickets, survey answers, notes, anything with text
];
const result = Broccoli.cluster(docs, { algorithm: 'lingo' });
for (const topic of result.clusters) console.log(topic.label, topic.size);
// result.clusters: [{ label, size, documents, … }], plain JSON
Or as an ES module: import * as Broccoli from 'https://cdn.jsdelivr.net/gh/GenesisL1/Broccoli@v1.5.0/dist/broccoli.mjs'
Switch between the maps at any time; the place you are in stays. Every shape carries its name and its number of records, so colour is never the only cue.
Every topic is a cell of a weighted power diagram whose area is its share of the records, relaxed into rounded, organic shapes. Subtopics grow inside their topic's cell, and shapes morph as you zoom.
Topics as circles packed to fill the map. The beads along a bubble are its subtopics; open one and it becomes the background while its subtopics spread out over the map.
A sunburst. Topics share the inner ring by size; their subtopics and sub-subtopics fill up to two rings outside, each within its parent's angle.
A head of broccoli seen from above. Each topic is a floret on a stem from the centre, and every record a bud on Vogel's sunflower spiral.
All four maps show the same PubMed search: longevity[tiab] AND (aging[tiab] OR ageing[tiab]), the first 200 records with abstracts that PubMed returned by Best Match, clustered by Lingo.
Click a topic and Broccoli zooms into it while it clusters that topic's records again, on the spot. The words of the labels on the way down are set aside, so a subtopic is never just its parent's name again. It goes as deep as the records allow, up to six levels.
Broccoli implements three classic methods of search results clustering from their published descriptions, tuned for abstracts and search snippets. Pick one per search; every parameter is open in the settings.
Concepts first, names second.
Factorises the term–document matrix into concepts, by partial SVD or non-negative matrix factorisation, then names each concept with the best phrase the records share. Labels are descriptive, and a record can sit in several topics.
Shared phrases become topics.
Finds every phrase the records repeat, with suffix and LCP arrays in linear time, scores the phrases as base clusters and merges those that share most of their records.
Split, and split again.
Spherical k-means splits the largest group in two, keeping the best of five trial bisections, until there are enough groups, and names each group by the terms that set it apart.
| Lingo | STC | Bisecting k-means | |
|---|---|---|---|
| Labels | one phrase, usually very descriptive | up to three phrases | the top terms of the topic |
| Topics | overlapping | overlapping | a partition: every record in one |
| Best for | 100 to 2,000 abstracts or snippets | fast runs on phrase-rich text | when every record must land somewhere |
GenesisL1 is built on the idea that a result should be something anyone can reproduce. Broccoli brings that idea to reading what a search returns.
Clustering happens in a Web Worker in your browser. There is no clustering server, no account and nothing to install.
Queries go from your browser to the source you pick, or to a proxy you host. No source needs a key or an account, and settings stay in your browser.
Every random step draws from a seeded generator. The same records with the same settings always give the same topics and the same map.
Broccoli is lexical: no embeddings and no language model. Every label is made of words from the records, highlighted in each record.
Eight matte hues in a fixed order, computed in the OKLab colour space. Names on every fill at 4.5:1 contrast or better, neighbouring colours checked for colour-blind separation, and light and dark themes from the same palette.

On a phone the source tabs scroll sideways and the map runs edge to edge; the page never scrolls sideways, down to 320 pixels.
PubMed is where GenesisL1 uses Broccoli first. GL1X, the explorer of the GenesisL1 blockchain, runs it for its PubMed search: every molecular structure on the chain links to its literature, by its PDB ID and by the important words of its title, and the papers open as a map of topics.
AI agents connected to GL1X's MCP server reach the same records through its pubmed_search tool, with the MeSH headings they share.
pubmed_search at gl1x.com/mcp.Broccoli is GenesisL1’s in-house engine, released under the MIT License by Decentralized Science Labs LLC. Every method is implemented from its published description, and the notices credit each one, along with every data source. Read it, fork it, run it on your own site.
The symmetric eigensolver is ported from JAMA, released to the public domain by The MathWorks and NIST. The stemmers were written from the Snowball descriptions by Martin Porter and the Snowball project.
Short answers to what people ask first.
Broccoli is a GenesisL1 in-house open-source search results clustering engine. It takes the records a search returns, groups them into topics named in the records’ own words, and draws the topics as a zoomable map, all in your browser.
It is GenesisL1’s own engine, developed in house by Decentralized Science Labs for the GenesisL1 ecosystem and open source. GL1X, the GenesisL1 explorer, runs it for its PubMed search, where every molecular structure on the chain links to its literature.
No. Eleven sources are built in: PubMed, Europe PMC, ClinicalTrials.gov, preprints, arXiv, OpenAlex, Crossref, DOAJ, DataCite, INSPIRE-HEP and Wikipedia. Any other search API plugs in, and the library clusters any text records you give it, from survey answers to support tickets.
It is free and open source under the MIT License. There is no account, nothing to install and no API key: none of the eleven sources needs one.
From your browser straight to the source you pick, or to a proxy you host. Nothing passes through GenesisL1, and your settings stay in your browser.
With one of three published algorithms: Lingo, Suffix Tree Clustering or bisecting k-means. Broccoli is lexical, with no embeddings and no language model, so every label is made of words from the records, highlighted in each one.
Up to 2,000 records a search, fetched within each API’s rate limits. Click a topic and Broccoli clusters its records again into subtopics, up to six levels deep.
Each source sets its own pace, and Broccoli keeps to it. OpenAlex, which the OpenAlex and arXiv tabs read, gives every address a daily allowance of about fifty searches of 200 records; it renews the next day, and the other sources keep working.
Yes. The library is one script with no dependencies. Load it from jsDelivr or copy it from GitHub, add your own search with registerSource or jsonSource, or call cluster() on your own records.
Not directly. Google’s Custom Search JSON API is closed to new customers and due to shut down on 1 January 2027, so the open general search here is Wikipedia. A web search API that needs a secret key plugs in through a small proxy of your own.
Search, cluster, zoom and read, in your own browser, from eleven sources or your own. Open source, made in house for the GenesisL1 ecosystem.