RoundsRx was built on a simple idea: residents should not just memorize what to do, they should understand why they are doing it. Every protocol, every drug choice, every clinical decision is grounded in the landmark trials and current guidelines that shaped it. When you understand the why, you stop cramming and start thinking like a physician.
It covers 268 clinical topics and tools across 15 rotations, from ICU protocols and cardiology to nephrology, heme/onc, and palliative care. Each topic is built around how residents actually work: pimp questions for rounds prep, clinical case scenarios, drug tables with brand names and dosing, trial citations with hover descriptions, and "updated practice" flags that highlight where old teaching has been overturned by new evidence.
Beyond clinical content, RoundsRx includes a media library with medical movies, documentaries, TV series, and recommended books for residents, plus a curated resources page with clinical guidelines, tools, and textbook recommendations, because residency is more than just medicine.
© 2026 RoundsRx. All rights reserved.
This application, including all clinical content, source code, design, and underlying data structures, is the proprietary intellectual property of RoundsRx. Unauthorized copying, redistribution, modification, reverse engineering, or creation of derivative works is strictly prohibited.
You are granted a personal, non-transferable, non-exclusive license to use RoundsRx for your own clinical education and patient care. Commercial use, resale, or republishing of any part of this application requires written permission from RoundsRx.
The printable one-page sheets in the Infographic Library may be printed, photocopied and handed out at no charge for teaching and patient care, including by residency programs in orientation materials, provided each sheet is reproduced unaltered with its RoundsRx footer and QR code. Selling them, or re-hosting the files on another website, requires written permission; please link to the page instead.
index, follow, a self-referencing canonical, and a unique title and description), plus one remaining defect. A hardcoded FAQ structured-data block (GCS intubation, sepsis fluids, gout, lupus and ten more) shipped on every page, so the intra-abdominal infection page claimed in its schema to answer the hyponatremia correction rate. Google requires FAQ markup to match what is visible on the page, and an identical block site-wide reads as duplication. A second FAQ block was also being generated on each page, and only one is allowed. The static block is gone; each topic URL now describes only its own pimp questions, and the multi-view homepage emits none.X-Robots-Tag: noindex. Four real, deployed, sitemap-listed pages were in that state, including Outpatient Hypertension, Refeeding Syndrome, Legionnaires’ Disease and the new High-Altitude Illness page. Adding a topic to index.html was never enough; it had to be registered in the edge function too, and nothing enforced that. Now registered, and audit.js gained an edge-function-unregistered check that fails HIGH if any sitemap URL is absent from both maps. The existing view-isolation guard could not catch this, since it samples six URLs and these pages never reach the stripper at all.lastmod 2026-04-12, so Google had no reason to re-crawl and the validation it ran on 5 September re-checked five-month-old data. Refreshed 247 lastmod dates to reflect the work actually done since, and added the one view that was missing from the sitemap entirely (Legionnaires’ Disease). Verified first that all 285 sitemap URLs map to real views, so nothing dead is being advertised.toggle('reveal') instead of toggle('revealed')- so clicking them did nothing and the answer could never be seen. Affected thyroid storm, hypercalcemia, antiphospholipid syndrome, scleroderma renal crisis, ANCA vasculitis, adrenal crisis, rheumatoid arthritis and gout. Separately, two older card formats showed the question and answer together with nothing to reveal: 12 cards in syncope and corticosteroids used a plain Q/A text block, and 12 more in Ebola and CKM split the question and answer into sibling elements so both rendered openly. All 24 were converted to proper tap-to-reveal cards. Two topics had exactly one question each (PMR/giant cell arteritis and hypoparathyroidism), too few to page through, so each was given a full set of 8 verified questions covering the steroid dose that differs between PMR and GCA, why starting steroids does not ruin the temporal artery biopsy, why calcitriol is used rather than ordinary vitamin D, and why the calcium target is deliberately low-normal. Final state, verified by clicking every card on the site: 222 of 222 topics render a carousel, and all 1,376 answers reveal correctly.verify-qr.py uses OpenCV, such a code fails our verification, and shipping an unverifiable QR on a sheet whose whole purpose is being scanned is not acceptable. The fix went into the generator rather than the one file, since hand-patching a PNG is overwritten on the next run: gen-qr.py now decodes every code it produces and steps the minimum version up until it succeeds, keeping error correction at M for print robustness, and aborts loudly if no variant works. That self-check flagged four further sheets -airway RSI, lower GI bleed, inpatient diabetes and hypothyroidism- whose regenerated codes were also undecodable. Their published PDFs were checked directly and decode correctly, so nothing in the wild was broken; the exposure was prospective, in that re-rendering any of them would have quietly produced a sheet with an unscannable code. All five were regenerated and re-rendered, and the library verifies at 216 of 216./CLAUDE.md returning 200 with its full contents, and every infographic HTML source under /infographics/_src/ being served the same way, even though a forced 404 redirect for that exact path had been sitting in the Netlify config. The reason is an ordering rule that is easy to get wrong: edge functions run before the redirect engine. The Open Graph edge function matches every path, and the call it makes to fetch the page reads the static file directly, so the redirect was never reached on any URL. Blocking is now done inside that edge function, ahead of its static-asset shortcut so that source images cannot slip through on their file extension, and the config rules were kept as a fallback in case the edge function is ever removed. The PDFs, thumbnails and everything else under /infographics/ stay public, since those are the product. The .git and .claude folders were checked and are not served at all.CONFIRM_2021 while the visible trial card still read "2024 · NEJM", as did one inline citation. Verified against the primary publication: CONFIRM was published in NEJM on 4 March 2021 (Wong et al., N=300, HRS-AKI reversal 32% vs 17%). Both display instances corrected to 2021. The same check confirmed the other six RCT_DB key removals this cycle were duplicate cleanups, not data loss: each removed key (ISIS_2_1988, MADIT_II_2002, PARADIGM_HF_2014, PROVE_IT_2004, Girard_ABC_2008, HI_PEITHO_2026_DB) still exists under its dash-form equivalent, and there are zero dangling references to any removed key, so no tooltip is broken.qr-* pocket-card guides whose category label reads "Quick Reference", the "Quick Reference Card" headings inside One Pager sections, and content headings such as "Murmur Quick Reference", none of which are topic tabs.print-btn in the topic hero and 97 op-print-btn inside the One Pager sections, 322 in total across all 204 clinical topic views. The new printOnePager() reads the current view, looks it up in a generated IG_PDF map, then loads that sheet into a hidden iframe and calls print on it, so the dialog opens on the one-pager itself. The old behavior printed the whole topic page, which for most topics runs to many browser-rendered pages; the sheets exist precisely so a resident can carry one. Because not every browser lets a script drive an embedded PDF viewer, a short timer opens the sheet in a new tab if printing did not fire, and navigates to it if the popup is blocked, so the button never does nothing. All 197 map entries were verified to point at a PDF that exists on disk, including topics served by a shared sheet, so aortic stenosis and mitral regurgitation both reach the valvular sheet and the three rare infections reach the combined one. The 13 views without a sheet keep the old behavior deliberately (the qr-* pocket cards and the library are already printable pages), as does the QR poster, where the poster is the page. The map is generated, not hand-maintained: gen-qr.py now rebuilds IG_PDF from the manifest alongside IG_GO, so adding a sheet and re-running it keeps the buttons current. The visible labels were changed too, which the first pass missed: the button read "Print Protocol" on 134 topics and plain "Print" elsewhere, so the behavior had changed while the wording still promised the old thing. All 309 buttons now read "Print Infographic", keeping their existing printer icon. The 13 views with no sheet were deliberately left reading "Print", since those fall back to printing the page and labelling them "Print Infographic" would be a promise the button cannot keep. The sheet opens in a new tab only. The first build fell back to navigating the current tab when the browser refused a popup, which under local file mode happened every time and took the reader off the app. It now opens via a synthetic anchor click, which inherits the button's user gesture and is not popup-blocked, and the same-tab path was removed entirely: navigating away unloads the single-page app, so going Back would mean a full reload of a very large document and losing your place in the topic.copd-exacerbation-management already defined "the 6 P’s" twice more, with different members each time: a triggers table (pneumonia, PE, pneumothorax, pleural effusion, poor compliance, pollution) and a summary tile (pneumonia, pollution, PE, pneumothorax, pump failure, pills). Three lists under one name, on one page, for one disease. The deeper problem was that the triggers list was not a list of triggers. A pulmonary embolism, pneumothorax or effusion does not set off an exacerbation, it is the diagnosis instead of it, so four of those six were mislabeled. Resolution: the page now has exactly one 6 P’s, the alternative diagnoses, being PE, Pneumonia, Pneumothorax, Pump failure, Pulse (ACS or arrhythmia) and Plug or aspiration. The former triggers table is retitled Common Precipitants, keeps its content, and gains a column stating for each entry whether it is a precipitant, the diagnosis itself, or both, since an airway infection precipitates a true exacerbation while an infiltrate means pneumonia rather than AECOPD. The summary tile and the rounds checklist item that called PE a trigger were corrected to match, and sheet #38 was rebuilt on the same six, gaining the previously missing Plug and aspiration entry. PE leads the list as the highest-yield miss: roughly 1 in 6 hospitalized patients with an unexplained exacerbation, pooled 16.1%, with 68% of those emboli in main, lobar or interlobar arteries, so it is not subsegmental noise Aleva, Chest 2017.[/regex/i, replacement] array form rather than as objects, and the word-boundary escapes must survive being written to the file, since a first attempt wrote literal backspace characters instead of , which would have produced regexes that silently never matched. The new terms were validated by reintroducing a British spelling and confirming the check failed the build.audit.js now reports this as a deploy-blocking finding, naming both the outer and inner element, and it rides along on the existing browser render at no added cost. The check was then extended to every card class on the site, not just rotation cards: it now covers all 9,539 card elements across roughly 30 classes, including summary cells, alert boxes, pearl cards, example boxes, trial cards, infographic cards and calculator cards. It flags only a card nested inside another card of the same class, which is always a mistake, while ordinary nesting inside a different container stays silent. Validated by reintroducing the bug, which correctly produced the finding and a failing exit code.search event previously fired only when someone clicked a result, which meant the most useful signal, the searches that returned nothing, was never recorded. It now fires on the query itself with a results_count parameter, recorded above the no-results branch so both outcomes are captured. It is debounced 1.2 s so a burst of keystrokes produces one event rather than one per letter, ignores queries under 3 characters as noise, and dedupes a held query. The click is now its own search_result_click event, so "what residents looked for" and "what they actually found" are finally separate questions. Verified in-browser: three rapid queries produced a single event, a nonsense query recorded results_count: 0, and a real query recorded 10 results followed by a distinct click event. Note this needs search_term, results_count, topic_id and destination registered as GA4 custom dimensions to be visible; the property currently has none registered, so every custom parameter the site sends is collected and then unqueryable, and registration is not retroactive.Hyponatremia -3-Step Approach -RoundsRx, and that tight space-hyphen reads like a typo in a search result. All 271 titles in index.html and 251 in the edge function now use Hyponatremia | 3-Step Approach | RoundsRx. The replacement targeted only space-hyphen, so genuine hyphens survived intact: GLP-1, Lung-Protective, 3-Step and Non-Hodgkin are unchanged. Five pieces of runtime code also parsed the old format to build breadcrumbs and share-email subjects, and were updated in the same pass, since otherwise every breadcrumb would have displayed the full title with its suffix still attached.stripNonTargetViews() finds each view's end by counting div depth, and five views are missing their own closing tag (the browser silently recovers, a depth counter does not), so those views were never stripped. These were the same MEDIUM "unclosed-tag" findings the audit has reported for months and that were treated as cosmetic because the browser renders fine. Fix: the stripper now clamps every view's range at the next view's start, so a malformed view can no longer swallow its neighbors, with the last view bounded at </main> so the scripts and closing tags survive. Verified against the real file: previously 3 foreign views leaked into every page, now exactly 1 view is served per URL out of 250, roughly 86 KB smaller per page, with an unknown slug still safely returning the full document. A regression guard now runs in audit.js ("SEO view isolation"): it executes the real stripper against six representative URLs, including the first and last views, and fails the deploy if any URL serves more or fewer than exactly one view, if the target view is stripped, or if the document tail is destroyed. It was validated by reintroducing the bug, which correctly produced a HIGH finding and exit code 1. This class of defect was invisible for months because every existing check reads index.html, while the fault lived in the edge function that only crawlers ever see.dateModified and lastReviewed refreshed to 2026-07-30 in both the static head block (was 2026-05-01) and the dynamic per-topic block (was 2026-03-07). Sitemap lastmod updated only for the pages that actually changed this cycle (home, About, palliative extubation, infographic library) rather than blanket-bumping all 248 URLs, since lastmod should reflect real edit dates. Service worker cache bumped to roundsrx-v15 so returning users pick up this build instead of a cached copy.id="infographic-library" view under the Tools nav group collecting the full RoundsRx Infographic Series. 56 print-ready A4 PDFs grouped into 10 categories (Sepsis & Infection 12, Cardiovascular 10, Respiratory 7, Toxicology & Emergencies 6, Gastro & Hepatology 5, Neurology 5, Renal & Metabolic 5, Airway & Procedures 2, General ICU Care 2, Hematology 2). Each card shows a preview thumbnail and opens the vector PDF, which stays sharp when zoomed or printed. 47 of the 56 are also embedded directly in their parent topic under the One Pager tab: 28 replaced an existing HTML one-pager, 14 got a brand-new One Pager section and tab (necrotizing fasciitis, RSI, acute liver failure, malignant hyperthermia, fat embolism, PADIS sedation/delirium, fungal infections, brain death, massive transfusion, radiology quick-ref, anticoagulation reversal, hyperkalemia, antibiotics, anaphylaxis), and 5 were appended to quick-reference views that have no tab structure (ACLS, vasopressors, inotropes, electrolyte replacement, shock/differential trees). Search is preserved: where an infographic replaced an HTML one-pager, the original text was retained inside a collapsed "Text version" block, so every term stays findable through global search and readable by screen readers. All asset paths are root-relative (/infographics/...) so they resolve correctly on SPA deep links rather than 404-ing under the topic path.localStorage (roundsrx_pimp_v1), counts show live in the toolbar, and "Clear stars/known" resets. Navigation now walks a filtered working-list rather than the raw priority order. First step toward true interval scheduling if usage warrants it.id="renal-drug-dosing" section in the CKD Medications tab. Six why-driven tables (~37 drugs) covering the STOP/avoid list (NSAIDs, metformin, nitrofurantoin, glyburide, spironolactone, IV bisphosphonates, sotalol, group-I gadolinium), antibiotics (vancomycin, aminoglycosides, cefepime neurotoxicity, vanc+pip-tazo AKI, carbapenems, fluoroquinolones, TMP-SMX pseudo-Cr-rise, acyclovir), anticoagulants (apixaban as preferred DOAC + 2-of-3 reduction, dabigatran/rivaroxaban/edoxaban thresholds incl. the edoxaban >95 paradox, enoxaparin 1 mg/kg daily <30), diabetes (SGLT2i initiate ≥20/25 and continue to dialysis, glipizide-over-glyburide, insulin reduction, linagliptin no-adjust), cardiovascular (digoxin, renally-cleared beta-blockers, ACEi/ARB ≤30% Cr-rise rule, rosuvastatin max 10 if eGFR<30), and analgesia/neuro/misc (gabapentinoids, morphine M6G accumulation, allopurinol titrate-to-target, colchicine, lithium, iodinated contrast). Every row states the GFR/CrCl threshold, the action, the why, and a renal-friendly alternative ("use instead" column): e.g., acetaminophen for NSAIDs, apixaban/warfarin for the other DOACs, atorvastatin for rosuvastatin, denosumab for IV bisphosphonates, febuxostat (with CARES caveat) for allopurinol, fentanyl/hydromorphone for morphine, metoprolol/carvedilol for renally-cleared beta-blockers, group-II gadolinium for group-I. CrCl calculator linked; thresholds verified against KDIGO/ADA 2025 and current labels. Deep-linked into the section from four sibling topics where the question arises: AKI (medication review step), antibiotics (renal-dose table cross-reference), anticoagulation (DOAC renal dosing), and outpatient diabetes (metformin dose-by-eGFR).id="bnp-interpretation" block in the Acute HF Workup tab. Two why-driven tables, conditions that raise BNP (cardiac: HF, AFib, ACS, valvular, myocarditis; non-cardiac traps: age, CKD, PE, pulmonary HTN/COPD, sepsis, female sex, anemia/high-output) and conditions that keep it deceptively low despite real HF (obesity via NPR-C clearance, hyperacute flash edema, HFpEF, constrictive pericarditis/tamponade, compensated chronic HF). Plus a clearance-mechanism box explaining the BNP-vs-NT-proBNP differences and the ARNI trap from one fact (BNP cleared 3 ways including neprilysin; NT-proBNP renal-only): why CKD raises NT-proBNP more, obesity lowers BNP more, and why sacubitril/valsartan makes BNP unreliable so NT-proBNP is the marker to trend on Entresto. Age-adjusted NT-proBNP cutoffs included, plus a "Which to order: BNP vs NT-proBNP" decision box (equivalent for dx/prognosis so use what the lab runs; NT-proBNP if on an ARNI; lean BNP in advanced CKD; never compare values across assays, trend the same one). Five passing BNP mentions site-wide (STEMI, qr-labs, lab-guide, TACO/TRALI discriminator, and the HF workup row) deep-linked to this canonical section. ARNI-affects-BNP caveat propagated to the chronic HF GDMT topic (Congestive HF GDMT monitoring table + workup), since that topic recommends ARNI as pillar #1 while also recommending BNP trending, the two collide, so both monitoring mentions now flag "on Entresto, trend NT-proBNP not BNP" with a deep-link back to the why.id="intractable-hiccups") rebuilt into a full singultus reference, definitions (acute <48h / persistent >48h / intractable >1 month), the reflex-arc rationale for the broad differential, causes ordered by frequency (GI, drugs incl. dexamethasone, CNS/Wallenberg with stroke deep-link, phrenic-vagus irritation, metabolic), targeted workup, and a corrected treatment ladder. Clinical fix: chlorpromazine was mislabeled first-line; per current evidence baclofen and gabapentin are first-line (tolerability) with chlorpromazine the only FDA-approved agent but held in reserve (sedation, hypotension, QTc, EPS). Same correction propagated across the topic’s symptom-overview table, summary cell, and one-pager so all four mentions agree.id="pseudothrombocytopenia" box in the ITP Workup tab making it the "rule out FIRST" step for any isolated low platelet count. Covers the EDTA / GPIIb-IIIa / calcium-chelation clumping mechanism, the smear-confirms-clumps diagnostic step, and the key nuance that a manual count on the same clumped EDTA tube is also falsely low (clumps defeat any counting method), so the fix is removing the clumping, redraw in citrate (×1.1 dilution correction) or heparin, and/or warm to 37°C, not switching counting technique. Closes with why it matters (avoid needless transfusions, steroids, marrow biopsy, held anticoagulation).id="cohen-woods-lactic-acidosis" section in the Acid-Base topic. Two-type framework (A = hypoperfusion/hypoxia, B = everything else) with B1 (underlying disease: liver failure, malignancy, sepsis, thiamine deficiency, short bowel/SIBO), B2 (drugs/toxins: metformin, linezolid, propofol, NRTIs, β₂ agonists), B3 (inborn errors: mitochondrial, PDH deficiency). New D-lactic acidosis alert covers the SIBO/short-bowel mechanism (gut bacteria ferment carb to D-lactate, the stereoisomer humans cannot clear), episodic encephalopathy presentation, and the standard lactate assay measures L-lactate only trap (order a D-lactate level specifically). Sits inside Type B1 in Cohen-Woods.id="milk-alkali-syndrome" breakdown (CaCO₃ antacids + milk → hypercalcemia + AKI + alkalosis triad, mechanism, classic vs modern presentation, distinguishing from other hypercalcemia causes). Cross-linked from the Acid-Base CLEVER PD "Excess alkali" row using the established showView + scrollIntoView deep-link pattern so the passing mention navigates directly to the deep explanation.id="severe-cap-definition" section makes ICU-disposition criteria explicit (IDSA/ATS major and minor criteria) so the "severe CAP" label triggers cefepime + vancomycin per SSC 2026 rather than ceftriaxone + azithromycin. New id="steroids-in-pneumonia" section covers when steroids help (severe CAP / refractory shock, CAPE COD 2023), when they do not (non-severe CAP, viral pneumonia), and which steroid + dose.id="acs-2025-guideline-changes" section consolidates what changed in the 2025 ACC/AHA ACS guideline at a glance (DAPT duration shifts, P2Y12 selection nuances, routine PRECISE-DAPT/DAPT-score risk-tiered de-escalation) with tag-driven NEW / CHANGED / UNCHANGED columns following the editorial "always state guideline changes" rule.indexnow-submit.js a second time pushing all 247 URLs to api.indexnow.org (200 OK), Bing IndexNow (200 OK), and Yandex IndexNow (202 Accepted); (2) diagnosed the GSC "Crawled - currently not indexed" validation failure (135 pending, 3 failed as of May 2, 2026) - verified via curl-as-Googlebot that the live edge function correctly serves per-URL unique title, self-canonical, unique meta description, JSON-LD MedicalWebPage schema, X-Robots-Tag: index, follow, ~18 KB of unique visible text per page, and strips 245 sibling views per request (only 1 target view div + 245 stripped placeholders served); (3) sitemap.xml lastmod bumped to 2026-05-27 only for genuinely-changed entries (homepage, dyslipidemia-guideline-2026, outpatient-lipid-management, type-2-diabetes-outpatient) - deliberately did NOT blanket-bump unchanged URLs since Google detects fake freshness and penalizes it; (4) orphan-URL cleanup: caught two stale sitemap entries (/inpatient-insulin-management and /toxicology-toxidromes-antidotes) whose view divs had been renamed to /inpatient-diabetes-management and /toxicology-drug-overdose. The edge function's safety-bail was serving the dashboard for these URLs, creating exactly the duplicate-content signal that drives "Crawled - currently not indexed". Added 301 redirects in _redirects and pulled the stale entries from sitemap.xml. Conclusion documented: "Crawled - currently not indexed" is now a quality/authority signal, not a technical bug; resolution path is backlinks + time + "Request Indexing" per-URL in GSC, not more code changes.<details> blocks for visual density. Default closed; click ▶ to expand. Search index still finds them via textContent.<details> collapsibles still indexed because textContent ignores display state.RoundsRx is an educational tool designed to support -not replace -clinical judgment. All content is evidence-based with trial citations, but medicine evolves rapidly. Always verify drug dosing with your pharmacy, confirm guidelines with your institution, and use primary sources (UpToDate, society guidelines, package inserts) for patient care decisions. RoundsRx is not responsible for clinical outcomes.
Built by residents who got tired of flipping between five apps on rounds. Content sourced from major society guidelines (AHA/ACC, KDIGO, IDSA, ATS, AASLD), landmark clinical trials, and UpToDate -then distilled into the format we actually need at 3 AM.
Special thanks to the attendings who pimp relentlessly -you made this necessary.
Found an error? Have a topic request? Want to contribute? Reach us at RoundsRx@gmail.com. We read every email and prioritize corrections within 24 hours.