A faster, rustier Element Web

October 29, 2026
Engineering
A faster, rustier Element Web

Dave Baker and Florian Duros (Element) at The Matrix Conference 2026.

Element Web is moving onto the Matrix Rust SDK, the same foundation that powers Element X on mobile. Our team isn't doing it as one big rewrite. They're rebuilding the app one piece at a time as reusable shared components that don't care which SDK sits underneath. At The Matrix Conference 2026, Dave Baker and Florian Duros showed how far that work has gotten since FOSDEM 2026, and how it has already improved in the Element Web people use today.

Dave is a staff software engineer at Element and also sits on the Matrix Spec Core Team. Florian is a senior software engineer at Element. He and Florian work together on Element Web.

How Element Web got here

Dave started with history. Element Web began in 2015 as Vector (later Riot), and he showed a screenshot of a very early 2016 version: very simple, and very fast. The client grew alongside the Matrix spec, which was much simpler back then, and features were added as the protocol grew.

From the start, the team wanted to build the client from reusable parts. That was the idea behind the Matrix React SDK: a library of React components you could compose into a different app, with Element as a thin skin on top. In practice it didn't work out. The components held all their own logic and were tightly coupled to the app and to each other, so lifting one into another app was hard. In Dave's words, the name "was misleading: it wasn't really an SDK". The team retired it in 2024 and merged it into Element Web.

Why not just rewrite Element Web on the Rust SDK?

Element X, Element's newer mobile client, is built entirely on the Matrix Rust SDK. Dave listed what that brings: it was designed from the ground up to be fast and stable, it has supported end-to-end encryption from day one (the older React and JS SDKs predate end-to-end encryption), and it's built around Sliding Sync to make the app usable immediately after it was started. Android and iOS share that same Rust SDK, so there's more code reuse. Having web on it too would be great.

A straight rewrite of Element Web has real problems, though. Moving from the Element Classic mobile apps to Element X took multiple years, and Element Web has even more features than those apps did. A new app would also mean migrating users, or making administrators switch web clients for them, and running two clients in parallel the whole time.

Dave went through the alternatives and why the team rejected them:

  • Freeze new features until the rewrite is done. Not realistic: customers won't accept waiting for features until a migration finishes.
  • Build every feature twice, once for each client. That means maintaining two clients for the whole migration.
  • Speed things up with LLMs. The team wants all their code reviewed by humans to keep a high quality bar.

There's also the team's direct experience. Element Web already uses Rust for encryption, via the Rust crypto library compiled into the app. That migration alone took over two years and was, as Dave put it, "at least five times" more complicated than you'd expect.

The underlying problem is that Element Web is tightly tied to the JavaScript SDK it's written against, with little separation between the two. The goal is to keep the app's UI and swap the SDK beneath it.

Shared components and the MVVM pattern

Florian explained how shared components solve this. They live in a separate package with no technical coupling to Element Web, and therefore none to the JS SDK. They're also bigger than the basic building blocks in Compound, Element's existing design system. Florian's example was a full room picker dialog that a module could reuse.

The components follow MVVM (model–view–view model), the pattern Element already uses in its mobile apps:

  • The model is the data layer, in this case the SDK.
  • The view is the UI component, with no business logic.
  • The view model connects the two and acts as an abstraction layer between the view and the SDK.

Views live in shared components. To switch SDKs, you write a new view model and leave the UI alone. That way work such as accessibility improvements carries straight over. Florian said the switch should be close to "plug and play" for developers.

The team also added new tooling along the way. Every shared component has a Storybook entry with screenshot tests for each state, which cuts down on visual regressions and speeds up development.

What's already shipping in Element Web

Several recent Element Web features are built this way:

  • A completely rewritten timeline, now in labs. Florian said it no longer has jumping issues and is more reliable, though it's still in development.
  • User status.
  • Sections at the top of the room list.
  • New link previews.

Existing parts of the app are being moved over too, including the EventTile component that renders timeline items, which Florian called a huge piece of work. The user menu, room list and emoji picker have also moved. The team's rule is that when they work on an existing feature, they take the time to move it into shared components.

The demo: Storybook and Aurora

Florian showed the Storybook setup. The room list appears in every state (flat list, sections, loading, empty), and you can drill down to a single room list item. He then showed the same components running in Element Web and in Aurora, a proof-of-concept client built on the Rust SDK. The timeline was the same component in both.

Dave explained why Storybook matters to the team. It holds every component in the app and doubles as a test suite. For the user menu, for example, there are preset states with very long names, so the team can check that truncation with an ellipsis works without starting the whole app. Developers can also change a component and see the result straight away without logging into Element Web.

He described Aurora as a test bed with "a much lower bar on code quality", built as a hackathon project and updated from his own LLM-driven pull requests. It is not ready for production, which he reminded us of as a click on a room filter failed to respond live on stage! The point is that its components come straight from Element Web, so Aurora gets those features just by importing them.

Questions from the audience

What happens when the components are done? Dave said the team is still deciding. One option is a toggle between JS SDK and Rust SDK modes, possibly requiring a log out and back in. The downside is shipping the Rust SDK to everyone, including people who don't use it. Another is a build flag that produces Element Web in either mode, which Dave thought might be more sensible. Either way, only one SDK can run at a time. Once one SDK syncs, the server treats those events as delivered, so the other SDK would never receive them.

Can I use these components in my own projects? Yes. They're in the Element Web monorepo, alongside the web app and shared utilities. Dave said this finally delivers what the React SDK was meant to do: take a component like the room list, write a view model for it, drop it into a React app and build your own chat client.

Has the JS SDK changed to make the move easier? Not much. Dave explained that one approach would be to make the JS SDK look more like the Rust SDK and swap the bottom layer. The team chose to work at the higher level and swap the top layer instead. Florian added that the two SDKs have different architectures and paradigms, so writing a new view model per SDK is easier than forcing their APIs to match.

How far along is the project? Not all components have been converted yet, and the work has mostly happened in the background, whenever the team touches a feature. Speeding it up is a question of priorities. The next big milestone is actually putting the Rust SDK into Element Web.

Learn more

The shared components are available now in the Element Web monorepo for anyone who wants to build with them. For the full demo, watch the talk on YouTube.

Related Posts

By the same author

Be in your element.