Aha! Develop is the agile tool that links strategy to delivery.


Learn more
Jeremy Wells · 2025-03-03 · engineering, ruby

Rails views, web components, React. Why make a choice?

How many times have you heard or read statements like these in tech discussions?

"Everything needs to be a single-page app these days. Server-rendered templates are holding you back."

"Web components are the future. Why tie yourself to any framework?"

"Islands architecture is the way forward. We were right about server-rendered templates all along!"

"Just use React for everything. That's what Meta uses, right?"

Each opinion delivered with absolute conviction, each speaker certain they've found the One True Path to front-end enlightenment.

We've had plenty of these discussions at Aha! too. But somewhere between the enthusiastic debates about client-side versus server-side rendering, we realized something interesting: These technologies aren't mutually exclusive. In fact, they can work together remarkably well.

This isn't a story about hedging our bets or failing to make a decision. It's about how we discovered that Rails views, web components, React, and Rails ViewComponents each have their sweet spots.

And when you use them together thoughtfully, you end up with something more powerful than any single approach could offer. Let me show you how we make this work — and why choosing all of the above might be more practical than you'd think.

The false dichotomy

There's something comforting about picking a lane and sticking to it. As engineers, we love consistency, patterns, and clear decision trees. It's almost a relief when a team can say, "We're a React shop" or, "We're all in on server-side rendering." It simplifies hiring, architecture decisions, and tooling choices.

This drive toward technological monogamy makes sense. After all, mastery requires focus, and nobody wants their codebase to look like a museum of web development history. We've all seen those applications — jQuery here, Angular there, a dash of Vue, wrapped in a Rails template. It's the stuff of maintenance nightmares.

But here's where it gets interesting. When we dig into the arguments for each approach, we find they're all solving real problems.

Rails views advocates aren't wrong when they point out the simplicity of request/response patterns, the joy of convention over configuration, and the performance benefits of server rendering. When your feature is primarily about displaying data with basic interactions, anything more complex is often overengineering.

Web components champions make excellent points about vendor lock-in and the appeal of using native browser features. Being able to drop a <custom-datepicker> into any framework (or no framework at all) is powerful. Plus, they're future-proof in a way that framework-specific components can never be.

And yes, the React ecosystem's rich component libraries and battle-tested patterns for managing complex UI state are invaluable for certain types of features. When you need sophisticated client-side interactions, fighting the framework is usually more painful than embracing it.

The bigger picture isn't about which approach wins — it's about understanding that these technologies evolved to solve different problems. The real question isn't, "Which one is best?" but rather, "Which one is best for this specific feature?"

Our tech stack at Aha!

Aha! is, at its heart, a Rails monolith. And we're proud of that. After 10 years of growth, our application remains a testament to the power of Ruby on Rails' "convention over configuration" philosophy. But like any application that grows with users' needs, we've evolved our approach over time.

Here's how these technologies fit together in our stack:

  • Rails views still form the foundation of our UI. They're fast to develop, easy to maintain, and perfect for the bread-and-butter features that make up much of our application. Why reach for something more complex when Rails views do the job beautifully?

  • Rails ViewComponents came into our tool kit as we recognized common patterns across our views. They give us the benefits of component-based architecture (reusability, encapsulation, testability), all while staying firmly in Ruby-land.

  • Web components emerged as our bridge between worlds. They're our secret weapon for sharing functionality between Rails views and React components. Need that custom date picker to work everywhere? Make it a web component and it just works, regardless of where it's used.

  • React powers our most interactive features, like planning with Gantt charts and the rich responsive interfaces in Aha! Develop. We're selective about where we use it; React is a tool in our tool kit, not the entire tool kit itself. When we do use React, we don't skimp. We've built our own state-management framework to make development easy and consistent. This has allowed us to build complex pages, like the workflow board in Aha! Develop, where real-time updates and interactions need to feel effortless.

The key to making this work isn't just using multiple technologies — it's understanding how they complement one another. A Rails view might include several ViewComponents for common UI patterns, use web components for interactive elements, and embed a React component for a complex data visualization. Each piece does what it does best, working together to create a cohesive whole.

When to use what

Let's break down how we think about each technology and where it shines. Rather than abstract examples, I'll share real scenarios from our codebase that helped shape our decisions.

Rails views

Rails views remain our go-to for most views. Following both Rails and our own internal standards, we can build features very fast using Rails views. When we combine this with pre-built components of various kinds, pages can come together quickly.

An example of views in Aha! that don't venture far off the beaten path of Rails templates is the settings pages. These are mostly forms and options, with some information tables.

Rails ViewComponents

ViewComponents came into play when we noticed we were repeating similar view patterns across the application that were still expressed best as Ruby code and Rails templates. For example, showing a button with a dropdown that renders a list of models (like those related to workflow). It is too specific to be a web component, although it will certainly leverage web components for the dropdown. And it could be a React component, but that would add complexity for a simple use case.

Web components

Web components are our bridge between different parts of the application. They work best for very generic cases, like a button, a button with a dropdown, a date picker, or a special kind of radio button. They let us use the same visual style and UX from Rails views and React components.

Methodology selection

Selecting a methodology? This is based on web components.

React

We reach for React when we need rich, stateful interactions that would be cumbersome to build any other way. Real-time updates, drag-and-drop interactions, complex state management — these are exactly the kinds of feature where React's strengths shine through.

There are many places in Aha! that use React. These might be embedded in Rails views (like the collaborative editor) or used to display most of a page (like the Gantt chart for planning and many of our interactive charts).

Making them work together

We believe in trusting our engineers to make the right technical decisions for their features. When you build something new, you decide which technologies to use. You have the context of how you've solved similar problems before, a team ready to discuss approaches, and clear examples of each technology in action.

This process works well at Aha! because we have strong conventions and a collaborative culture. You might start building a feature using Rails views because that's the simplest approach. Later, you might realize one interaction would work better as a web component. Or perhaps during development, you discover the feature needs more complex state management than you initially thought, and you refactor part of it to use React.

Nearly every page in Aha! is a mix of these technologies. However, rather than a mess where new doesn't quite yet replace old, or where engineers have disagreed about the vision, we've made the mix intentionally. Each technology serves its purpose: Rails views provide the structure and standard interactions, web components ensure consistency across the interface, ViewComponents encapsulate complex Ruby-based view logic, and React powers our most interactive features.

The key is that these decisions emerge from real needs rather than theoretical preferences. When you're building and maintaining your own features, there's a natural accountability that helps you overcome any personal bias toward a particular view technology. With a supportive team behind you — and good examples in front of you — practical solutions win out over philosophical preferences.

What if we're wrong?

It's a fair question. What if our choices today turn out to be mistakes? What if web components fall out of favor, or React becomes yesterday's news? The reality is that any code we write today might need to change tomorrow. But because we've kept each technology in its lane and maintained clear boundaries between concerns, we're not locked in. We could replace our web components with whatever comes next, swap out React for a different framework, or even move more toward server-rendered views if that proves better for our needs.

This flexibility is another benefit of not betting everything on a single approach. When you're pragmatic rather than dogmatic about technology choices, changing course becomes an engineering challenge rather than an existential crisis.

Choosing your own path

The tech world loves to tell stories about the "right way" to build web applications. Rails is dead, everything must be React, web components are the future … you've heard it all before. These absolutes make for great blog posts and conference talks, but they rarely reflect the reality of building complex products that delight users.

Aha! engineers have learned that pragmatism beats purism every time. By embracing multiple technologies and letting each play to its strengths, we build better software faster. More importantly, we keep our focus where it belongs: on solving real problems for our customers.

The next time someone tells you that you must choose between Rails views, web components, or React, remember that the best path might be the one you forge yourself. What technologies are you mixing in your projects?


Does this blended approach resonate with you? We have open engineering roles — join us.

Jeremy Wells

Jeremy Wells

Jeremy is a principal software engineer at Aha! — the world’s #1 product development software. He likes thinking about software architecture and problem solving at any level of the software stack.

Build what matters. Try Aha! free for 30 days.

Follow Aha!

Follow Jeremy