MedNama-SIH25: One Diagnosis, Four Codes: MedNama's Bridge Between Ayurveda and ICD-11

A student hackathon project takes on India's hardest health-IT problem: making traditional medicine legible to the systems that already exist.

8 min read • View on GitHub • More from indrasuthar07

An overhead view of a physician's desk with two open reference books side by side. On the left, an Ayurvedic diagnostic chart with hand-drawn body regions and Sanskrit labels; on the right, a modern ICD-11 tabular list with columns of alphanumeric codes. A single pen lies across both books, and one entry on the Ayurvedic chart is joined to one entry on the ICD list by a single taut thread.
Two systems, one diagnosis. India's answer is to carry both codes on the same record, which is harder than it looks.
Key Takeaways

A clinician in an AYUSH clinic writes down amavata. It is a specific, well-defined diagnosis in Ayurveda, with its own etiology and its own treatment logic. Now open a biomedical EHR. There is no ICD-11 code that means the same thing.

A Diagnosis That Doesn't Fit Anywhere

This is not a gap that better search fixes. The two systems are not two labels for one disease. They carve up the body differently. Ayurveda reasons about doshas and agni and the accumulation of ama; biomedicine reasons about inflammation and autoimmunity and joint destruction. You can say they overlap. You cannot say they are the same code with a different name.

India's answer has been to stop pretending they collapse into one. The Ministry of AYUSH maintains NAMASTE, a code system for Ayurveda, Siddha, and Unani diagnoses. The WHO maintains ICD-11, which includes a Traditional Medicine Module 2 (TM2) for exactly this overlap. The goal is not to translate one into the other, it is to carry both codes on the same patient record so that a biomedical system can read the record without losing the traditional diagnosis.

MedNama-SIH25 is a student's attempt to build that record. It was created for Smart India Hackathon 2025, it has three stars, and it is the kind of project worth reading closely because it shows you the shape of the correct answer and then the distance between that shape and a working system.

Four Codes, One Condition

Here is the thing MedNama gets right. A diagnosis in this system is not stored as a string. It is stored as a FHIR R4 Condition resource whose code field is a CodeableConcept containing four coding entries: one for ICD-11, one for NAMASTE, one for TM2, and one for Biomedicine.

That array is not an accident. FHIR's CodeableConcept.coding is an array precisely so that one clinical concept can be expressed in multiple code systems at once. It was designed with this exact multi-system mapping in mind. Choosing it is the single most technically meaningful decision in the repository.

const buildFHIR = () => ({
  resourceType: "Bundle",
  type: "collection",
  entry: selected.map((d, idx) => ({
    resource: {
      resourceType: "Condition",
      id: `cond-${idx + 1}`,
      clinicalStatus: "active",
      verificationStatus: "confirmed",
      code: {
        coding: [
          { system: "ICD-11",     code: d.icd,            display: d.display },
          { system: "NAMASTE",    code: d.namaste,        display: d.display },
          { system: "TM2",        code: d.code,           display: d.display },
          { system: "Biomedicine", code: d.biomedical,     display: d.biomedical_name }
        ],
        text: `${d.display} cross-system mapping`
      }
    }
  }))
});

Look past the shape and two problems surface immediately. The system values are plain strings like "ICD-11" and "NAMASTE", but FHIR requires canonical URIs (http://id.who.int/icd/release/11/mms and similar). A FHIR validator would reject these. This is FHIR-shaped JSON, not FHIR-valid. And the TM2 coding reads d.code, a field that does not exist in the source data file, which matters more than it sounds.

How one typed term becomes four codings on one Condition. Toggle between the system as written and a FHIR-valid version to see the gap.

How One Search Becomes a Bundle

The pipeline is short enough to hold in your head. A clinician types into a search box. A 400 ms debounce fires a request to GET /api/icd-search. The backend loads the entire terminology file with a synchronous fs.readFileSync on every request and does a substring match across six fields: icd, biomedical, namaste, biomedical_name, display, and description.

The clinician selects a result. The front end builds the FHIR Bundle, POSTs it to /api/save-diagnosis, and Express stores the whole bundle as a Mongoose Mixed type. Storing FHIR whole is pragmatic, since the format is deeply nested, but it means you cannot query inside it or enforce its structure later.

Two honest details about the search. Ranking is a single sort: entries whose display starts with the query float to the top, everything else keeps its original order. An exact code match and a substring buried in a long description rank equally. And the synchronous file read is fine for a few hundred rows, but the official NAMASTE codebook has thousands of entries. At national scale, this blocks the event loop on every keystroke.

A tight close-up of a physical filing box labeled 'Bundle.' Inside, four envelopes are stacked, each labeled with a different code system and a different code string written on its face. A hand holds the box open, revealing the top envelope.
The FHIR Bundle, made physical. Four envelopes, one box, one diagnosis.

Where the Prototype Ends

The gaps here are not subtle, and they are worth stating plainly because they are what separates a demo from a system.

The ABHA login is a setTimeout. Any 14-digit string passes. There is no OAuth flow, no call to an identity provider, no token, no session. The consent checkbox is never sent anywhere. The route is commented as a protected layout, but nothing protects it: no auth guard, no token check, no redirect. The GET /api/saved-bundles endpoint has no authentication, pagination, or filtering, so anyone who can reach the server can read every stored diagnosis.

The most consequential bug is in duplicate detection. Search results come from data.json, which has no code property, so term.code is undefined. The guard reads if (!selected.find(d => d.code === term.code)), which evaluates as undefined === undefined and is true for every already-selected item. The first diagnosis can be added. Every later attempt is silently rejected. The multi-diagnosis workflow that the FHIR Bundle was built around cannot work.

"Version 2.1" appears in the footer of a repository created a month earlier. The claim of WHO-compliant terminology integration describes a hand-curated JSON file. None of this is unusual for a hackathon build. It is what a prototype looks like when the demo matters more than the deployment, and it is useful to see the gap written down next to the code.

The Crowded Field

NAMASTE and ICD-11 dual-coding was a popular problem at SIH 2025. Several teams shipped something, and MedNama is one of the thinnest of them. Comparing on the axes that matter, what each team actually built and what they claim, is more useful than a feature list.

ProjectWhat it isDocumented strengthsDocumented gaps
MedNama-SIH25React + Express EMR front end with a dual-coded FHIR exportIdiomatic four-coding Condition; clean shadcn UISimulated auth; multi-diagnosis bug; no terminology service
CodeVedas SIHFHIR R4 terminology microservice for NAMASTE + ICD-11 TM2Redis-backed ranking, semantic search, multilingualSearch service only; not a full EMR
AYUR-SYNC-APIFHIR-oriented API with CodeSystem, ValueSet, and ConceptMapRelease snapshots, provenance, caching, consentParts marked prototype or roadmap
AYUVA / SWASTIPatient-facing conversational symptom toolsMultilingual, patient engagement focusNot a terminology service; different niche

A note on evidence: MedNama's details are drawn from the repository itself. The other three are drawn from their public descriptions and should be treated as reported, not audited. CodeVedas and AYUR-SYNC both describe terminology-service features that MedNama does not have at all, which is the honest reason to look at the field rather than the single repo.

What Real Dual-Coding Would Require

To move from FHIR-shaped to FHIR-valid, the four system fields become canonical URIs. To move from a hand-curated JSON file to a terminology service, you add proper relevance ranking, caching, and a release-aware snapshot so a code means the same thing next year. To move from a setTimeout to an identity flow, you wire ABHA for real. To move from a student's guess at a crosswalk to a clinical mapping, you have the mapping reviewed by people who practice both systems.

MedNama gets the shape right. It gets the substance wrong. That is a fine starting point and a bad finish line. The reason to write it down is that the shape is the part that is hard to see, and the substance is the part that is merely work.