Inspiration
Indonesia is home to an estimated 30,000+ plant species. Of those, roughly 1,845 have been identified as having medicinal use and only around 283 are officially registered with BPOM, Indonesia's food and drug regulator, as standardized herbal medicine. Sit with that gap for a second: out of nearly two thousand plants with documented traditional medicinal use, fewer than one in six has ever been formally recognized. The other five are living on borrowed time, passed down by jamu makers and traditional healers who are aging out of practice, to generations who increasingly have no reason to believe any of it works.
And yet. In the 30 species we chose to study in depth for this project a tiny fraction of Indonesia's medicinal flora we found 11 compounds that are molecule-for-molecule identical to drugs already approved and prescribed in modern medicine: levodopa, the frontline Parkinson's drug, sitting quietly in Mucuna pruriens seeds used for generations as a tonic. Reserpine, one of the first modern antihypertensives, in Catharanthus roseus and Rauvolfia serpentina. Mitragynine the compound at the center of today's kratom research and regulatory debate in Mitragyna speciosa, long used in Kalimantan and Sumatra. These were not new discoveries. They were already there, in plants people have been using the entire time. Nobody had simply connected the dots between the traditional-use record and the chemistry.
That's the gap this project exists to close not between jamu and science, but between evidence that already exists in a dozen disconnected databases, and a form where it can actually be seen. If 11-out-of-30 species already have an exact chemical match to an approved drug, what is sitting undiscovered in the other 97% of Indonesia's documented medicinal flora that nobody has had the time to map? We built Materia Medica Nusantara to start answering that question systematically, transparently, and honestly including about everything we still don't know.
What it does
Materia Medica Nusantara is a research dashboard that links 663 scientifically documented Indonesian jamu plant species to modern pharmacological evidence, built from five independent public data sources and two original NLP pipelines that mine knowledge directly out of free text rather than relying only on pre-structured database tags.
Concretely, for any of the 663 species, the dashboard shows:
- Identity & taxonomy — scientific name, Indonesian local names (often several regional names per species), botanical family, and a photo.
- A historical name timeline — scientific names the species was known by in the past, each with its publication year (as far back as 1753), reconstructed from PROSEA's synonymy records. This is "mapping plant names across eras" made literal and visual.
- Traditional uses — ethnobotanical records of what the plant is traditionally used for, sourced from Dr. Duke's USDA database, plus free-text descriptions from PROSEA.
- NLP-extracted conditions — symptoms and conditions pulled directly out of that free-text description using a custom spaCy-based matcher, independent of any pre-existing tags.
- Known phytochemical compounds and their reported pharmacological activities.
- An automated "evidence tier" — whether modern PubMed literature contains clinical, preclinical, or no evidence at all for this species, with the explicit caveat that "no evidence found" is not the same as "doesn't work."
- For 30 flagship species: real compound structures from PubChem, and the results of an RDKit cheminformatics model comparing those structures against 40 reference drugs — flagging compounds that are chemically identical to an approved drug versus ones that are merely structurally similar (a screening signal, not a claim).
- An interactive knowledge graph (plant → traditional use / compound → pharmacological activity) for any species, and a reverse search from a pharmacological activity back to candidate species.
How we built it
Data pipeline (src/pipeline/, 15 Python scripts)
| Source | What we pulled | License |
|---|---|---|
| PROSEA (Plant Resources of South-East Asia), via the Pl@ntUse wiki | Taxonomy, Indonesian vernacular names, free-text traditional-use descriptions, dated scientific-name synonyms | Academic wiki content |
| Dr. Duke's Phytochemical and Ethnobotanical Databases (USDA/ARS) | Compounds per plant, pharmacological activities per compound, ethnobotanical use records, all with literature references | CC0 (public domain) |
| PubMed, via NCBI E-utilities | Automated literature counts (general / clinical trial / review) per species | Public API |
| PubChem, via PUG REST | Real compound structures, SMILES, molecular formula and weight | Public API |
| Wikipedia / Wikimedia Commons | A representative photo per species | Per-image license shown in the dashboard |
We started from 1,392 PROSEA medicinal-plant pages, filtered to 663 species with a confirmed Indonesian vernacular name, and joined them against Dr. Duke's database (pruning its global tables down to just these 663 species, since 99% of Duke's ~13,000-species dataset isn't relevant to this project).
Two original NLP layers, not just data joins:
- A regex/wikitext parser recovers PROSEA's "Synonyms" sections — which record historical scientific names together with their publication year — into 1,021 dated historical names across 490 of the 663 species, spanning 1753 to the present.
- A spaCy
PhraseMatcherrunning over a hand-curated, 14-category condition lexicon reads the free-text "Uses" paragraph of every species directly, extracting 2,313 condition mentions across 611 of the 663 species — built specifically because PROSEA's prose uses archaic pharmacological register ("stomachic," "emmenagogue," "febrifuge") that no general-purpose or biomedical NER model reliably recognizes.
Cheminformatics model: for 30 flagship species, we resolved their known compounds to PubChem, converted each to an RDKit Morgan fingerprint (radius 2, 2048 bits), and scored Tanimoto similarity against 40 reference drugs separating exact molecular matches from merely similar ones.
Knowledge graph: built with networkx (Plant → TraditionalUse / Compound → Activity schema),
exported as both GraphML and node-link JSON.
Dashboard: a Streamlit app (src/app/) with a custom design system (styles.py) — five tabs
(Overview, Plant Library, Network Explorer, Search by Activity, Structural Similarity), an
interactive pyvis knowledge-graph renderer, and altair charts.
Tech stack: Python, pandas, networkx, Streamlit, spaCy, RDKit, Altair, pyvis, Pillow, requests.
Challenges we ran into
- A C++ build failure on deploy. We'd experimented with
scispacyfor biomedical NER before realizing its vocabulary doesn't cover PROSEA's archaic pharmacological language, and pivoted to a custom spaCyPhraseMatcherinstead butscispacy'snmslibdependency was still sitting inrequirements.txt. It built fine locally but failed on Streamlit Community Cloud's build environment with a bare "installer returned a non-zero exit code." We rebuiltrequirements.txtfrom only the packages actually imported in our source and verified it in a brand-new virtual environment before redeploying. - A permission block led to a better design decision. Our first attempt at NLP extraction was
to install a pretrained biomedical NER model (
scispacy'sen_ner_bc5cdr_md), but it's distributed as a raw tarball rather than through a package index, and our sandbox's safety classifier correctly blocked that as an uncontrolled external download. Rather than finding a workaround, we reconsidered the problem and realized a trained biomedical model wouldn't have recognized PROSEA's 19th/20th-century pharmacological vocabulary anyway. The curated-lexicon +PhraseMatcherapproach we built instead was the right tool for this specific text, not a fallback. - A silent data-corruption bug in the dashboard itself. Early in the UI redesign, our entire
CSS stylesheet started rendering as visible text at the top of every page. The cause:
Streamlit runs Markdown through a parser before HTML, and our indented
<style>block was being parsed as a Markdown code block. We only caught it by actually screenshotting the running app in headless Chrome rather than trusting that "no exceptions were thrown" meant the UI was correct a reminder that automated tests and visual QA catch different classes of bugs. Headless screenshotting also caught a second bug in the Search-by-Activity tab: its default selection (the alphabetically-first activity,'Smart-Drug') matched zero species, so the tab opened on what looked like an empty, broken page. - A false positive in our own similarity model. Our cheminformatics pipeline flagged a
"compound" called
COUMARINS(plural a Duke's database category label, not a specific molecule) as chemically identical to warfarin. PubChem's name search had resolved the generic plural term directly to warfarin's own record. We caught it by manually inspecting every "identical match" result rather than trusting the pipeline output, and added the term to an exclusion list alongside other non-specific category labels (TANNINS,ALKALOIDS, etc.). - Wikipedia rate-limiting during image collection. Fetching photos for 663 species hit stretches where Wikipedia's API silently stopped returning thumbnails for dozens of species in a row. We built a separate retry pass with exponential backoff, which recovered most of the missing images on a second attempt confirming it was transient throttling, not missing data.
Accomplishments that we're proud of
- 11 compounds identical to approved drugs, found in a dataset we built ourselves rather than taken from an existing curated list including levodopa, reserpine, atropine, scopolamine, and mitragynine.
- Two genuinely novel NLP contributions, not just structured-data integration: a historical name-timeline feature spanning 273 years, and a from-scratch condition extractor tuned specifically to archaic ethnobotanical English that off-the-shelf NLP models cannot handle.
- A dataset that scaled from an initial 300-species pilot to the full 663-species candidate set without sacrificing per-species depth or data quality.
- A dashboard that is explicit about its own uncertainty everywhere it matters "no evidence found" is never conflated with "doesn't work," and structural similarity is never conflated with proven efficacy.
What we learned
- The gap between "traditional medicine" and "modern pharmacology" is often not a gap in reality it's a gap in information architecture. The compounds and the evidence frequently already exist in public databases; they were simply never joined together in a place a person could look at.
- Generic NLP/NER tooling is tuned for contemporary text. Historical and ethnobotanical sources need either a model trained specifically for that register, or as we found works well at this scale a carefully scoped, transparent lexicon that you can audit by hand.
- Treat "no exceptions raised" as necessary, not sufficient. Several of our most significant bugs (the CSS leak, the empty default tab, the COUMARINS/warfarin mismatch) produced zero errors and would have shipped silently without a human actually looking at the rendered output and the model's literal conclusions.
What's next for Materia Medica Nusantara
- Expand from 663 species to the full set of documented Indonesian jamu plants.
- Grow the flagship/similarity-screened set beyond 30 species.
- Replace the hand-built NLP lexicon with a model trained specifically on historical pharmacological text, rather than a curated keyword list.
- Partner with pharmacognosy researchers to take our "structural analogue" findings into the lab for real validation the dashboard can tell you where to look; it can't replace a wet-lab assay.
- Reconcile species names across sources against a formal taxonomic authority (GBIF/WFO) instead of string matching, to catch synonym mismatches we currently miss.
Data sources & licensing
See the README for the full table PROSEA/Pl@ntUse, Dr. Duke's Phytochemical and Ethnobotanical Databases (USDA, CC0), PubMed/NCBI, PubChem, and Wikipedia/Wikimedia Commons.
Results at a glance
| Metric | Value |
|---|---|
| Species | 663, across 96 botanical families |
| Distinct compounds | 2,845 |
| Compound–activity relationships | 1,438 |
| Evidence tier | 98 clinical · 393 preclinical/review · 171 not found |
| Flagship species (PubChem + similarity model) | 30 |
| Compounds identical to an approved drug | 11 |
| Structural analogues flagged | 21 |
| Species with a dated historical name | 490 (1,021 names, 1753–present) |
| Species with NLP-extracted conditions | 611 (2,313 mentions, 14 categories) |