Last year, my mother started taking St. John's Wort for mild depression. She was also on blood pressure medication. Nobody told her those two interact — St. John's Wort can reduce the effectiveness of certain antihypertensives through CYP3A4 enzyme induction.
That scared me enough to build something about it.
The Problem
Herb-drug interactions are a real clinical concern that most people never think about. According to a 2019 systematic review in the British Journal of Clinical Pharmacology, approximately 1 in 3 adults in the US and Europe uses herbal supplements regularly, and up to 70% never tell their doctor.
The information exists — scattered across PubMed, FDA safety alerts, and pharmacology textbooks. But it's not accessible to the average person taking turmeric with their statins or ginkgo biloba with their blood thinners.
Existing tools either:
- Require a medical professional login
- Cover prescription-to-prescription only (no herbs)
- Are behind paywalls
- Have terrible UX
What I Built
A free, zero-dependency, static HTML tool that checks herb-drug interactions across 590+ documented combinations. No backend, no API calls, no tracking — everything runs in the browser.
Live tool: Verificador de Interacciones — Botánica Andina
The data layer
Every interaction in the database has:
- Severity level: major (contraindicated), moderate (use with caution), or minor (monitor)
- Mechanism: the pharmacological reason (CYP enzyme induction/inhibition, additive effects, absorption interference)
- Clinical evidence: PubMed DOI or reference for each entry
- Recommendation: practical guidance
Example entry:
{
"herb": "St. John's Wort",
"drug_class": "SSRIs",
"severity": "major",
"mechanism": "Additive serotonergic effects via 5-HT reuptake inhibition",
"evidence": "doi:10.1016/j.tips.2004.02.009",
"recommendation": "Avoid combination. Risk of serotonin syndrome."
}
The tech stack
Deliberately minimal:
- Pure HTML/CSS/JS — no frameworks, no build step, no npm
- Fuzzy search — users type natural language ("can I take turmeric with metformin?") and get matches
- Offline-capable — works without internet after first load
- Mobile-first — 80%+ of health searches happen on phones
- Accessible — ARIA labels, keyboard navigation, high contrast
Total bundle size: 47KB gzipped. Loads in under 1 second on 3G.
Why zero dependencies?
- Trust: this is health information. Users shouldn't need to trust 47 npm packages
- Longevity: no dependency rot. This will work in 10 years without maintenance
- Speed: no hydration, no virtual DOM, no framework overhead
- Auditability: any pharmacist can read the source and verify the data
Building the Data
This was the hardest part. I spent weeks cross-referencing:
- Natural Medicines Comprehensive Database — gold standard for evidence ratings
- PubMed systematic reviews — especially Cochrane reviews on herb-drug interactions
- FDA MedWatch — adverse event reports involving herbal supplements
- European Medicines Agency (EMA) herb monographs
Each interaction was validated against at least 2 sources. Severity classifications follow the Natural Medicines framework:
- Major: avoid combination, documented serious adverse events
- Moderate: use with monitoring, clinically relevant effect
- Minor: theoretical or minimal clinical significance
Coverage
The database currently covers:
- 47 herbs and supplements (turmeric, ginkgo, garlic, echinacea, valerian, St. John's Wort, ashwagandha, etc.)
- 23 drug classes (anticoagulants, antihypertensives, SSRIs, statins, immunosuppressants, etc.)
- 590+ specific combinations
Technical Decisions
Search
I implemented a weighted fuzzy search that handles:
- Typos ("tumeric" → "turmeric")
- Synonyms ("blood thinners" → "anticoagulants")
- Spanish and English ("cúrcuma" = "turmeric")
- Natural language ("what interacts with warfarin?")
The search runs entirely client-side using a custom Levenshtein distance implementation. No API calls, no latency.
Performance
The entire interaction database (590+ entries with full metadata) compresses to ~30KB. On a modern browser, search results appear in <5ms. Even on older devices, it's never slower than 50ms.
I chose to inline the data as a JS object rather than lazy-loading it because:
- The dataset is small enough to not matter
- Eliminates network dependency for search
- Makes offline use trivial
Deployment
Static files on a CDN. No server. No database. No downtime. Monthly cost: $0 (hosting included with domain).
Lessons Learned
1. Health content needs citations, not just "according to studies"
Every claim in the tool links to a DOI or specific publication. This took 3x longer than writing the content, but it's the difference between a useful tool and a random blog post.
2. Zero-dependency isn't zero-effort
Writing your own fuzzy search, responsive layout, and accessibility features takes more upfront work. But the maintenance burden drops to essentially zero.
3. The hardest part is curation, not code
The interaction database took 10x longer to build than the interface. Verifying clinical evidence, resolving contradictory sources, and classifying severity levels is genuinely hard work.
4. Mobile-first isn't optional for health tools
Analytics from the first month showed 83% mobile traffic. If your health tool doesn't work perfectly on a phone screen, it doesn't work at all.
What's Next
- Expanding to 800+ interactions by Q3 2026
- Adding interaction severity visualization (color-coded risk matrix)
- Multilingual support (Portuguese next)
- PDF export for pharmacist review
If you're interested in contributing to the interaction database or have suggestions, I'd love to hear from you.
Top comments (0)