DEV Community

Cover image for I Built a Medicine Cabinet Interaction Checker That Finds Hidden Risks Between All Your Supplements and Drugs at Once
Botánica Andina
Botánica Andina

Posted on

I Built a Medicine Cabinet Interaction Checker That Finds Hidden Risks Between All Your Supplements and Drugs at Once

The problem with checking one interaction at a time

Last year I built a herb-drug interaction checker that covers 154 medicinal plants and 203 medications. It works well for quick lookups — "does St. John's Wort interact with my SSRI?" — but I kept hearing the same complaint:

"I take 3 medications and 4 supplements. Checking them one pair at a time takes forever."

A typical older adult in Latin America might take metformin, lisinopril, and atorvastatin while also using maca, cat's claw, and garlic supplements. That's 3 × 3 = 9 potential interactions to check manually. Some people have 15+ items in their daily routine — that's 50+ pairs.

Nobody's going to sit there checking each combination. So dangerous interactions get missed.

What I built

The Medicine Cabinet Checker lets you enter everything you take — all your herbs, supplements, and medications — in one place. Then it checks every combination simultaneously and shows you:

  • A risk score (green/orange/red) based on the number and severity of interactions found
  • Every interaction with severity level, mechanism, and clinical significance
  • A PDF report you can print and bring to your next doctor's appointment

Everything runs in the browser. No data leaves your device. No accounts needed.

How it works under the hood

The tool is a single HTML file with no dependencies. Here's the architecture:

1. The knowledge base

All interaction data is embedded as JSON directly in the page. Each entry follows this structure:

{
  "plant": "Uncaria tomentosa",
  "drug_class": "Anticoagulants",
  "severity": "high",
  "mechanism": "Inhibits platelet aggregation",
  "source": "EMA monograph 2015"
}
Enter fullscreen mode Exit fullscreen mode

There are 592 documented interactions sourced from EMA (European Medicines Agency) monographs, ESCOP, and PubMed clinical studies. Every interaction has a citation.

2. Combinatorial matching

When you click "Check," the tool builds the Cartesian product of your herbs × your drugs, then looks up each pair:

function checkAllInteractions(herbs, drugs) {
  const found = [];
  for (const herb of herbs) {
    for (const drug of drugs) {
      const matches = interactions.filter(ix =>
        normalize(ix.plant) === normalize(herb) &&
        matchesDrugClass(drug, ix.drug_class, ix.drugs)
      );
      found.push(...matches);
    }
  }
  return found.sort((a, b) =>
    severityOrder[b.severity] - severityOrder[a.severity]
  );
}
Enter fullscreen mode Exit fullscreen mode

Drug matching is fuzzy — it checks both the specific drug name (e.g., "warfarin") and the drug class (e.g., "anticoagulants"), because most people know their medication name but not its class.

3. The risk score

The score isn't a simple count. It's weighted:

  • High severity interactions: +3 points each
  • Moderate: +2 points each
  • Low: +1 point each

A single high-severity interaction (like St. John's Wort + SSRIs → serotonin syndrome risk) immediately pushes the score to "caution" territory.

4. Report generation

The PDF report is generated client-side using the browser's print CSS. No server involved. The report includes:

  • Date and list of items checked
  • All interactions found, sorted by severity
  • Source citations for each interaction
  • A disclaimer about consulting a healthcare professional

This was deliberately designed so patients can hand it to their doctor. In many Latin American countries, patients see herbalists and pharmacists who prescribe supplements without checking what medications the patient already takes.

The hardest part: getting reliable data

Building the UI took two days. Building the interaction database took three months.

The problem is that herb-drug interaction data is scattered across:

  • EMA monographs — comprehensive but only cover ~120 plants, mostly European
  • ESCOP monographs — similar coverage, different format
  • PubMed studies — thousands of individual papers, often contradictory
  • Traditional medicine databases — mostly anecdotal, no severity grading

For Andean plants specifically — maca, cat's claw, aguaymanto, sacha inchi, muña, sangre de drago — the published clinical data is thin. I had to cross-reference pharmacological mechanisms (e.g., "this plant contains alkaloids that inhibit CYP3A4") with known drug interactions for those pathways.

Every interaction in the database has at least one published source. Where data was uncertain, I erred toward labeling it "moderate" rather than "low."

What I learned

1. Most people don't know their drug class. They know "metformin" but not "biguanide." The autocomplete needs to map brand names → generics → drug classes. I added 400+ aliases.

2. Herb names are chaos. "Cat's claw" has 15+ common names across Spanish dialects alone: uña de gato, garabato, bejuco de agua, paraguayo... The search needs to handle all of them.

3. Zero-dependency is worth the effort. The page loads in <1 second, works offline, and will never break because a CDN goes down. For health tools, availability matters more than fancy frameworks.

4. Print-friendly design is non-trivial. Getting the PDF report to look good required a separate print stylesheet. Tables that look great on screen break horribly in print. I ended up using @media print with completely different layouts.

Try it

The tool is free and open: botanicaandina.com/herramientas/botiquin/

If you work with patients who take both conventional medications and herbal supplements — especially in Latin America where traditional plant medicine is common — this might save you some time.

The full interaction checker for individual lookups is here: botanicaandina.com/herramientas/interacciones/

And the yerba mate caffeine calculator (because caffeine itself interacts with many drugs): botanicaandina.com/herramientas/mate/

All tools run client-side, no tracking, no accounts.

Top comments (0)