From Simple to Civic: What Happened When I Built the Thing Anyway

From Simple to Civic: What Happened When I Built the Thing Anyway

Published on May 4, 2025

GitHub Repository

“It’ll be difficult, but there is a study that might be able to help.”

It’s one of the oldest cliches in Hollywood: a character has a rare disease, and somewhere out there – buried in the system – is a clinical trial or research program that just might save them. It’s a trope because, for decades, it’s also been real.

We’ve grown used to the idea that even obscure conditions might be treatable, that diseases which used to guarantee a death sentence are now something you live with – not die from. What we don’t think about is what happens if the system behind that progress collapses.

Our Health ROI turns raw NIH data into citizen-powered advocacy in seconds. What started as a would-be snarky joke on social media turned into 300+ shares and endorsements from top researchers and public health experts. Why? Because defending NIH funding isn’t a partisan act. It’s foundational.

I, like a lot of Americans lately, have been watching the country quietly withdraw from life’s census. And without wading too deep into politics, I’ll say this: believing that public money should fund systems that keep society running doesn’t make you a leftist or a conservative. It just makes you someone who chose a “settlement-based lifestyle” over hunter-gathering.

I came across a post on Bluesky where someone floated the idea that Americans needed to see where their tax dollars went – they needed to feel it. She wrote:

Free idea: a website where you enter the name of your disease/injury/condition/procedure and get shirts, stickers, signs, etc with “NIH grand number X saved my life.”

She went on in the conversation to say that it could all be worked out from a simple form.

A simple form. Simple.

Any web developer who sees the words “website” and “simple” in the same sentence starts twitching like grandpa when he talks about the war. But, like any digitally-inclined citizen who likes to feel involved without leaving the house, I jumped in…to leave a “Well, ackshually” comment. But, I was going to do my research. I was going to show her how hard it was to find an API that could do this, and how much harder it would be to build something like this.

30 minutes later, I had a working prototype using the NIH RePORTER API. Turns out, it was “ackshually” simple.

So now the question was: is the juice worth the squeeze?

Is it worth building a site that pings three different government APIs, filters the results, and shows the users the exact funding behind the treatments that saved their lives – then gives them a way to contact Congress and defend that funding?

Yeah. That’s kind of the whole point of civic democracy.

But I didn’t want to build this just to prove a point. I didn’t want another portfolio piece I could wave around like Stewar from MadTV yelling, “Look what I can do!”

What started as a sarcastic reply and quick vanilla JS demo became something far more serious. I realized that for some people, this could actually matter. It could give them a void. It could make them feel heard. And for some, that might be enough to get them to tomorrow.

Also – let’s be honest – this was happening in the middle of yet another round of attacks on scientific research funding. NIH, like so many institutions that quietly hold society together, was under threat (still is).

So no, this wasn’t just a neat little build. This was something I believed in.

Before I touched Figma or started writing a single line of final code, I wrote out four non-negotiables for the project:

  1. It had to be for everyone. That meant screen readers, keyboard nav, old phones, rural connections – full accessibility across the board.

  2. It had to be shared. I gave myself a modest goal: 24 shares. Why 24? Because I had around 20-something followers on Bluesky. If I got more shares than that, it meant I had built something people cared enough to spread.

  3. It had to be usable and unique. The UI couldn’t be overwhelming, couldn’t bury people in options – but also couldn’t be sterile or forgettable. I wanted the site to have personality, while still being intuitive to use for anyone, of any age.

  4. It had to work. Would the message land? Would the search tool be fast? Would the language resonate? I had no idea. The only way to find out was to ship it – and hope it got enough attention to learn from.

With those four goals in mind, I sat down and started designing Our Health ROI.

The Design

Designing for accessibility doesn’t start with Lighthouse, it starts the moment Figma loads.

That empty canvas already has opinions. And if you’re not careful, your design will take shape without asking who it’s really for. Here’s how I kept the focus on people – especially those too often left outside of digital experiences.

Rule #1: Your Colors Don’t Get a Free Pass

Run every color through a WCAG contrast checker if you know it’ll be used in a component needing accessibility (background, font, etc.). Test every combination of your font and background colors. First thing. This isn’t a “maybe later” or a “we’ll do it live!” option. This is your pre-flight checklist. If you wait until after your components are built, it’s already too late and you’re going to end up repainting the house in production.

Also, remember the Jedi rule of design: AAA – Always Avoid Absolutes (looking at you, Anakin).

Avoid #FFFFFF and #000000 as much as you can (exception being box shadow and borders). They are harsh and can create afterimages – ghost-bleed effects when people blink after staring at high-contrast areas too long. Use soft off-whites and deep charcoal tones instead. Avoid the Sith tones.

Rules #2: Not Everyone’s Using a Mouse

Some users are on keyboards. Some are on phones. Some are on phones as keyboards. You’re designing for all of them.

That means…

Wireframes? Where we’re going we don’t need wireframes…

I skipped wireframes entirely and went straight to high-fidelity mockups.

That’s…not always smart.

But I was the stakeholder, the designer, the developer, and the candlestick maker. The only approval I needed was from Future Me – so I jumped ahead.

Still, I had structure in mind.

And because I wasn’t using TailwindCSS (on purpose), I needed that structure to live inside a reusable SCSS setup.

Tailwind’s great for fast builds, but if you’re aiming for long-term scalability, it can devolve into a utility-class casserole. I wanted something sustainable. Something with a little built-in order.

Also, if I’d given myself Tailwind, I’d have abused it. I know myself. I know my laziness. Tailwind allows for a lot of customization but also allows for you to get away with a lot and basically build the same as everyone else. SCSS forces me into a guardrail situation where I must pay attention to my design.

I also ditched Bootstrap long ago because I could spot it from a mile away.

Tailwind’s more flexible, sure, but over time, it’s easy to tell when something’s just Tailwind with prettier font weights (and that’s on the developer, not Tailwind…but I’d be that developer). I didn’t want this to feel like a template. I wanted it to feel like a message.

A sales funnel for democracy

Even though this was a civic site, I still approached it like a funnel:

Get users from entry to action in under two minutes.

So my first designed component was the condition search bar – the real “start here” of the site. I mocked it up in grayscale first, without distractions. But within minutes, I realized I needed my fonts and colors chosen early to keep things cohesive.

Once a user runs a search, they get back live data showing exactly how much NIH-funded research has impacted their condition. That’s followed immediately by a CTA to email Congress.

The flow mirrors a classic product funnel:

Only in this case, the “product” is scientific funding, and the action is holding elected officials accountable for it.

Slightly different than Amazon, just as simple, fast, and direct.

Designing for America is easy

I debated whether to go clean and modern – dark UI, soft gradients, muted tones. But I realized that when you’re asking people to email Congress, don’t fight the visual language of civic trust.

Red, white, and blue might be safe, but in this case it’s also effective. It didn’t need to be cool. It needed to feel familiar. Recognizable. Trustworthy. Like something that belonged in the realm of public service.

Most users would be on the site for under two minutes. A clean palette with intuitive contrast helped reduce bounce and encourage exploration without ever asking for too much.

I did opt for a dark mode for one weird reason (doctors hate him!) – accessibility.

We tend to treat dark mode as a design perk. LinkedIn sure does. But it’s not just about aesthetics. For some people, it’s the difference between using your site or leaving it.

There are users whose eyes are extremely sensitive to light. If a site doesn’t offer a dark mode and they don’t have to be there, they’ll bounce. On the flip side, some users experience a glow or halo around light text on dark backgrounds, which can make reading feel like squinting through fog.

Offering both light and dark modes isn’t an aesthetic choice – it’s an accessibility choice. When possible, give people control over their visual experience. They’ll stay longer, engage more, and actually read what you wrote.

It’s all about the details

With the Figma design done, I knew I’d need the following in my development before I ever started coding:

This wasn’t just about building something functional. It was about building something welcoming, something that respects time, ability, and attention span.

The Development

I originally built this in vanilla JavaScript.

Not React. Not Next. Just browser APIs and stubbornness. It was fun. It was a challenge. And it proved I could wire up multiple NIH endpoints in a plain ole HTML/JS app. But as I watched interest in the project grow (we’ll get to that), I realized that this could end up scaling. And if it did scale, vanilla wasn’t gonna cut it.

One choice to rule them all

I moved the project to Next.js with the App Router because it gave me exactly what I needed:

It let me focus on what mattered – user experience and data clarity – without rebuilding half the internet just to send an email.

 Styling with SCSS, not spaghetti

As mentioned earlier, I avoided Tailwind for this build. I wanted the discipline and scalability of SCSS and I’ve built (building) my own internal pattern using BEM-style class naming within Next.js’ modules (yes, even though I’m not really all that strict about it yet…I’m getting there!).

The SCSS architecture is split like this:

It’s not a full-blown design system, but it’s close enough to scale if someone else ever joins the repo.

Headless ui + framer motion = utility + delight

I used Headless UI for all interactive primitives (modals, lists, transitions). That kept my components unstyled, accessible, and easy to customize.

Then I layered in Framer Motion for micro-interactions:

The result is a site that feels response without ever feeling like it’s showing off.

Fast times at data high

NIH APIs aren’t exactly built for performance or consistency.

So I built a small data layer of Zod-validated fetchers in lib/fetchers/:

I didn’t want malformed data to blow up the user experience. Zod made it easy to catch errors before they reached the browser.

Of course, it’s not just about getting data, it’s about taking action on that data.

When a user finishes their search and decides to contact Congress, the app:

  1. Generates a data-informed message using prebuild scripts (messageTemplates.ts)

  2. Opens a form with editable fields and personalization options

  3. ends the message via Nodemailer, using SMTP credentials behind a server route

All email logic is isolated to lib/utils/sendSiteContactEmail.ts, and the messages are cleanly separated from the logic so they can be updated without touching the code.

There’s no user data stored. No analytics. No tracking. Just form > email > done.

This also means there’s no backend – at least not in the traditional sense. So how does data flow from the search to the contact form without tracking users or storing state? I used lightweight React Context Providers to manage modal visibility, search results, and user contact details. It’s scoped, simple, and scalable. No Redux. No Zustand. Just the state I needed, where I needed it.

By deploying on Vercel and using Next.js API routes, the app runs serverless, with email, search, and content handled at the edge.

Svg animations that respect the user

The site includes animated SVG icons – gradient-filled, motion-enhanced elements designed to give the page subtle visual energy. But here’s the part that matters:

If the user has “prefers-reduced-motion” enabled, the animation stop.

I used Framer Motion’s useReducedMotion() hook to check user settings and disable any motion or gradient animation accordingly. It’s a small thing. But to some users, it’s the difference between a page that feels nice and a page that feels safe.

Even the glow around the icons (animated with SVG filters and keyframed box shadows) dims gracefully if motion is off. Accessibility doesn’t mean removing delight, it just means making sure delight never gets in the way.

This was never about building a flashy frontend. It was about using thoughtful tech choices to make advocacy more accessible, to build a small but sturdy bridge between NIH data and the people it affects.

The Launch

This wasn’t supposed to take off. At least, not like this.

When I first shared Our Health ROI on Bluesky, the goal was modest: 24 shares. That was it. I had about 20-something followers at the time, and if more people shared it than followed me, I’d call that a win.

Instead, the app exploded (for having a small account).

Planning my move

The idea was simple: use the origin story as the hook ("It can't be that simple, right?") and let the app speak for itself. I focused my micro-campaign on three target audiences:

I seeded the launch primarily through Bluesky and LinkedIn. But it was Bluesky that carried it.

I never posted to X (Twitter). I didn’t even publicly post it to Facebook. I dropped the link in a private Facebook group with about 122 members (maybe 20 active). LinkedIn got zero traction. Bluesky did all the work.

Results in Context

By April 22, I added Vercel analytics.

Even without the first two days of data, the traffic curve aligns with the social sharing trend. If we extrapolate backwards based on the April 24–25 engagement ratio, the initial traffic surge was likely similar. Bounce (debounce) rate remained between 79% and 82%, right where I wanted it: fast visits, clear action.

As of today, the post has:

Referrers

Top sources of inbound traffic:

Notably, my LinkedIn post got zero engagement—no likes, no comments, no reposts. And yet, it drove the highest percentage of traffic. Why? Silent shares. Quiet influence. People passed it along without signaling. And honestly? I have no idea why. Like a block of code that works when it shouldn’t, LinkedIn became the biggest driver by accident, not intent—and I’m still trying to figure out how.

Tech Meets Timing

The most compelling detail of this launch wasn’t the metrics. It was who showed up. Professors. Epidemiologists. NIH-funded researchers. People who knew what the site was doing and instantly got the value.

That validated the entire mission. A sarcastic proof-of-concept accidentally gave people a tool they were hungry for.

And all it took was a search bar, a form letter, and a reminder that democracy sometimes starts with a web app.

Voices from the field

A tool is as good as the people who find it useful.

I launched Our Health ROI with some quiet hope and a lot of anxiety. I was worried the API wouldn’t scale. I was worried people wouldn’t get it. Then the errors started. 400s. 500s. And I thought that was it.

But the scientists kept sharing.

They kept refreshing, they kept linking, they kept posting their own screenshots and testimonials, despite the friction. They weren’t just supporting the project, they were defending the principle behind it.

“This is such a cool tool and exactly how we should have framed NIH research all along: Taxpayers fund scientists to understand disease and discover new treatments—and we deliver.”
—Microbiologist at a major public research university

“I know SO many people who haven't just survived but are thriving, post-diagnosis. This tool is awesome because it pulls the concrete numbers from the NIH website in a clearly accessible form.”
—Affective neuroscientist, UC Davis

“This is a really awesome widget, but it’s a sad way to discover the NIH has spent zero dollars on trying to fix y’all being so short.”
—Division Chief of Pediatric GI

Their praise came from labs, clinics, classrooms, and lived experience:

None of them followed me before. This was from outside my network.

And what made it especially humbling is they weren’t just sharing. They were interpreting. They used the tool in their own way, adding context I hadn’t even thought of. It gave their work a human face and gave this site a scientific soul.

This wasn’t a marketing campaign. It was just me trying to see if I could put together a small campaign and maybe get a few shares. Instead, people expressed how they were alive because of our tax dollars, and that’s not something I expected at all.

What I learned

I built Our Health ROI hoping that I’d have a cool build that helped a few people. What I got was something that touched the lives of a few hundred people, and I never expected I’d see quite a few “thank yous” thrown in.

The accessibility work paid off instantly. Within hours of launch, researchers praised the clarity, the layout, and the visual comfort. The site traveled further than I expected, appearing in LinkedIn Posts, Facebook threads, Substacks, and even private academic Slack groups. I didn’t fully grasp how powerful a dynamic OG card could be until I saw one get reposted dozens of times, often by people who never tagged me.

The copy helped, too. I wrote it like I talk. That tone tuned out to be disarming in a good way. Academics and scientists, often guarded by necessity, opened up about their research, their own personal conditions, and how the NIH had helped them.

Other things hit harder than expected. The launch was terrifying. 400 and 500s errors started rolling in while I was at work. I couldn’t fix them right away and so I immediately began to live every developer’s worst nightmare. But instead of collapsing, the users just kept trying. They refreshed. They sent me screenshots. They waited. And then it worked. They started posting about the solution to other people. It taught me something about trust, and about what people are willing to endure when they believe in something.

The other gut punch came later. One user loved the tool but was heartbroken to see only 3 research reports and 20 studies tied to their condition – something actively killing them. I thought it was a bug. I checked everything and bitterly concluded it wasn’t a bug. That’s all there was. I didn’t build this to highlight systematic gaps, but sometimes you use a flashlight to see what’s in the room only to find you’re shining it into an empty room.

Thankfully, most of the fixes were easy. My early API calls didn’t filter for NIH or government-only funding, which meant the results were sometimes inflated. A few conversations helped me catch that and fix it. I also learned that if an error can be solved by refreshing, you should probably just tell the user to refresh until you have a better solution, instead of letting the problem persist. Not everything needs to be solved immediately in the codebase – sometimes it just needs to be acknowledged.

Finally, I set out with a lot of different success metrics. I blew past all of them and learned that none of them really matter. I was embarrassed that I forgot to add site tracking sites until 2 days into launch, a rookie mistake, but now I’m kind of glad that I did. It forced me to realize that success isn’t get xx% increase in visitors per day, it’s a mother showing her daughter the search results and saying, “this is why you’re still here.” It’s a researcher realizing they’ve never seen their grant data presented so simply, seeing just what they’ve contributed to. It’s a scientist reposting it not because they were asked, but because they wanted to. That’s what mattered. That’s what still does.

Conclusion

In the end, Our Health ROI wasn’t just a site. It was a moment, a reminder that code can still connect people, not just sell to them. That a civic app can be useful and beautiful. That scientists, parents, patients, and professors can all look at a web app and say, “This matters to me.” It’s easy to forget in our industry that the simplest builds – when done with cares – can carry the most meaning. This wasn’t a startup pitch. It wasn’t monetized. It was just a tool people needed. And sometimes, that’s enough.

I didn’t build this to impress anyone. I built it because someone said it should exist, and they were right. But in building it, I realized that all the things I love – clear design, accessible code, impactful storytelling, ethical dev work – can live together in one place. This project didn’t change the world. But it did something. And if that something sticks with even a few people, then I’d do it all over again.