Skip to main content

The Landscape Beyond React

While React gets a lot of attention in web development circles, it is far from the only option for building scalable user interfaces for the web.

React has been a dominant feature of web development for over a decade now, which means it’s entirely plausible that you, dear reader, have spent most or all of your career working with React. If so, let’s go over some alternate approaches to rendering things on the web, and if not, stick around–you may still find something that piques your interest. There’s a whole world of options available, and they may end up being better for your particular needs.

Vanilla HTML, CSS, and JavaScript

This may seem like a weird place to start in an article about things you can use other than React, but you might be surprised at how good HTML, CSS, and JavaScript have become since React’s inception.

In HTML, we, of course, have the old mechanisms for interactivity (e.g., links and forms), but lately, we’ve been getting support for new elements that provide interactivity that used to require JavaScript. You can use <details> and <summary> elements to show and hide content, the newly available Popover API allows for accessible, tooltip-like interactions, and the <dialog> element vastly simplifies creating modal dialogs (although you still need a little JavaScript for that one).

In CSS, the :has() selector gives us the power to style elements based on parent elements, sibling elements, or even elements that are anywhere else on the page. The View Transition API allows us to animate between different pages, providing a single-page application (SPA) feel without all of the overhead required to build an SPA. New and upcoming features like CSS anchor positioning, fully styleable <select> controls, and being able to animate height to auto will further make it possible to make delightful interactions without resorting to JavaScript.

JavaScript itself has gotten some major upgrades, too. Around when React started taking off, there were resources like You Might Not Need jQuery that highlighted new JavaScript APIs that took inspiration from jQuery and became web standards. The humble querySelector, querySelectorAll, and addEventListener functions are useful on their own, but combine them with CustomEvent, and you can create a pretty simple state management system on your own. Yes, it means writing imperative code rather than declarative code, but by relying on native APIs rather than libraries, we can end up shipping far less code to users’ browsers overall.

Web components

While still technically under the umbrella of vanilla HTML, CSS, and JavaScript, web components are new enough and unique enough to be considered separately. The name “web components” is a bit of a misnomer, and it may lead you to believe that they’re meant to be native platform equivalents to React, but that’s not really the case. When we talk about web components, we’re really talking about three different things that can be used together (or not):

Custom elements allow you to define your own HTML tags (as long as they contain a hyphen, e.g. <example-tag>) that provide lifecycle callbacks. This solves a classic jQuery-era issue, where we used to have to wait for the DOM to load completely, then query for elements that we wanted to add event listeners to, and if new elements were added to the page later, we’d have to find and add event listeners to them, too. Now, we can just drop <my-component> on the page, and it will use the lifecycle hooks to do what it needs to do.

The Shadow DOM offers a way to keep an element separate from the rest of the main document DOM, keeping the element free from collisions with other scripts or styles. You probably don’t need the Shadow DOM most of the time, and you don’t have to use it. Here there be dragons, but if you need it, go for it.

HTML templates allow you to define reusable markup as the basis of custom element structures. This is useful for consistently defining components, and <slot> elements can further define and enforce those structures, but they do require the Shadow DOM to work. Again, HTML templates are completely optional, so if you want your custom element to be solely responsible for handling events through lifecycle methods, it can be.

Lately, we’ve been getting support for new elements that provide interactivity that used to require JavaScript.

Vue

For those looking for a more declarative, state-based approach to building user interfaces, Vue is and has been a great option for many years. Even though it was launched soon after React, which is on version 19 at the time of writing, Vue is only on version 3–a sign of stability and good API design. This also means less churn from needing to upgrade to newer versions, which can involve rewriting code to mitigate breaking changes.

Vue’s approach to components is more HTML-centric than React. The built-in directives like v-if, v-else, and v-for that are used for conditional rendering and looping are quite a bit simpler than React’s approach (or lack thereof), which usually requires writing ternary expressions or using array maps to render lists of things. Vue also uses two-way data binding, which simplifies getting/setting form data compared to React’s one-way approach.

Vue is built to work for a variety of use cases, ranging from simple jQuery replacement (petite-vue is an optimized subset of Vue built just for this) all the way to a fully-fledged server-side rendered application with Nuxt or Astro. Vue’s single-file components also strike a good balance between separation of concerns and keeping component markup, styles, and logic close together and easy to understand.

Svelte

One feature that makes Svelte distinct from other frameworks is that it works more like a compiler than a runtime. With React or Vue (or others), your authored components are interpreted and processed by the base library while the web application is running. With Svelte, all of your markup, styles, and logic get compiled into optimized JavaScript, which can dramatically improve performance, depending on the size of your application.

Svelte components are structured similarly to Vue’s single-file components, separating markup, styles, and logic into different sections within the same file, but the template syntax is more similar to handlebars or nunjucks, with blocks like {#if} to handle conditional rendering or {#each} to handle looping.

With Svelte’s compiler approach, they’re able to take more liberties with syntax since they control how the input translates into the output that lands in the browser. With version 5, Svelte introduced runes, which are just keywords that are part of the Svelte “language.” For example, $state is very similar to useState in React, but you don’t have to import it to use it.

A drawback of the compiler approach is that you must have a build step, which makes incrementally adding some Svelte to a project harder to do than dropping in a little bit of Vue or React.

React-likes (Preact, Solid.js, and Qwik)

If you’re used to React’s component structure and writing JSX, then you may want to consider some alternatives that have similar APIs but have different benefits. React has the “first-mover” advantage and popularity, but these React-likes have been able to innovate on React’s ideas without needing to manage its technical debt or deal with its legacy design decisions.

It’s worth noting that each of the options I’m about to describe uses some version of signals rather than React’s approach for managing state. Signals differ in implementation, but the basic idea is that signals allow you to get and set values and react to changes to those values using publish/subscribe (“pub”/“sub”) techniques. Signals have become widespread enough in different frameworks that there’s a proposal to standardize signals as part of JavaScript itself.

Preact is a lightweight alternative to React that mostly shares the same API. Its primary benefits are performance and better compatibility with the DOM specification. For example, Preact uses native DOM events instead of synthetic events, and it detects whether props should be treated as HTML attributes or properties, meaning you can write class instead of className. This is partially why web components have been supported by Preact for a while, whereas React only fully supports web components as of version 19.

Solid.js follows the same organizational structure as React, but it takes a similar approach to Svelte where it acts more like a compiler that optimizes code at build time. Solid also avoids some of the more frustrating issues that React has, such as useEffect dependency arrays and micromanaging re-renders, and they don’t use a virtual DOM, which minimizes overhead and improves performance. It also offers some conveniences, like a <Show> component for conditional rendering and a <For> component for rendering lists. Even with the compiler approach, Solid does support buildless setups, but doing so has performance implications, and the syntax is a little more awkward. SolidStart is Solid’s meta framework, similar to Next.js, for full-stack applications.

Qwik also closely matches React’s structure, but it prioritizes performance by delaying JavaScript execution as much as possible so that only the minimum amount needed gets used, and it uses resumability instead of hydration to handle interactivity. In short, this means lazy-loading application logic as needed rather than running all of the application logic up front. Qwik has its own meta framework, Qwik City, to handle server-side concerns like routing, middleware, and caching.

If you have the luxury of time, you could trial run each and see which performs better for your project and your team.

Honorable mentions: Astro and Eleventy

Astro doesn’t quite fit in with the other frameworks because it’s more of a “meta framework” that works with lots of other frameworks. You can use React, Vue, Preact, Svelte, or Solid with Astro, or some combination of all of them (not recommended). If you want, you don’t even need to use any of them, instead opting to write your components in .astro files with their own templating language, which is a superset of HTML. One of Astro’s main selling points is that it ships zero JavaScript by default, and it uses Islands architecture to only load JavaScript when needed.

Eleventy is a static site generator that supports many different templating languages, some of which (handlebars, EJS, or Pug) may be familiar to developers who’ve built websites using Express or its spiritual successors like Fastify. UI frameworks have their component-based architectures, but it’s worth noting that you can have similar architectures in traditional server languages or static site generators. They may not have the reactivity that UI frameworks offer, but that can be handled with vanilla JS or some of the lighter weight options discussed so far.

So, what should you use? It depends!

The aforementioned options only scratch the surface of the options available to developers, but they represent some of the most promising or proven alternatives to React for building websites. Ultimately, it is going to depend on your team’s experience and your project’s requirements to determine which approach works best.

If you have an existing project that is all-in on React and using Next.js or some other rendering strategy, it probably isn’t worth the cost to rewrite. But, if you’re only using React in the browser, then you might see some benefits from switching to Preact–first with preact/compat, then slowly refactoring pieces over time. If you’re building a brand new, complex application and all of your developers already know React, then Solid.js or Qwik might be a better option.

If you aren’t experienced with React but need the benefits of a UI framework, Vue or Svelte may be easier to learn. If you have the luxury of time, you could trial run each and see which performs better for your project and your team. If you only need a little bit of interactivity, then petite-vue might be the way to go, although you might be surprised at how much you can do with web components or vanilla HTML, CSS, and JS.

The web covers a wide spectrum of types of websites, ranging from blogs and marketing sites all the way up to highly interactive applications like maps and design tools. There is no one-size-fits-all approach, so explore your options, evaluate the pros and cons as best you can, and be willing to try something new (or old, as the case may be).

Want to talk about how we can work together?

Katie can help

A portrait of Vice President of Business Development, Katie Jennings.

Katie Jennings

Vice President of Business Development