Hydrogen: a Matrix web client that treats RAM as the scarce resource
Lightweight matrix client with legacy and mobile browser support
At a glance
- What is it?
- Hydrogen is a minimal Matrix chat client built for performance, offline behaviour and broad browser support, including legacy browsers, and it is deliberately a work in progress rather than an Element Web replacement. Its distinguishing move is architectural, offloading as much state as possible into IndexedDB, and it can be run as a standalone webapp or embedded into an existing site through an SDK.
- Who is it for?
- Adopt Hydrogen if you need a Matrix client for a constrained environment, an embedded chat inside an existing product, or a browser matrix that includes old clients, since the whole design targets low memory use and offline behaviour. Do not adopt it if you need feature parity with Element Web, because the project says plainly that it is work in progress, not ready for primetime, and asks that feature requests not be filed.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Matrix client written around a memory budget
Hydrogen is described as a minimal Matrix chat client, focused on performance, offline functionality and broad browser support, and the readme opens with a disclaimer that this is work in progress and not yet ready for primetime. Bug reports are welcome, but the readme asks that feature requests and other missing things to be on a par with Element Web not be filed.
That framing matters, because Element Web is the reference client and a lot of people arrive at Matrix expecting it. Hydrogen is positioned as something else, and the ask is a specific one: report what is broken, do not ask for parity with the full client.
The mechanism behind the performance claim is visible in the package description, which calls the project a javascript matrix client prototype, trying to minimize RAM usage by offloading as much as possible to IndexedDB. That is the architectural commitment. Rather than holding the session, the timeline and the room state in JavaScript memory, most of it lives in the browser's IndexedDB, and the app reads what it needs.
The stated goals follow from that. Work well on desktop as well as mobile browsers. UI components can be easily used in isolation. It is a standalone webapp, but can also be easily embedded into an existing website or webapp to add chat capabilities. And loading unused parts of the application after the initial page load should be supported.
The licence is AGPL-3.0 in the repository metadata, and the last push was on 2026-04-09.
The four goals, and the SDK that makes the third one work
The goals list is short enough to be quoted, and each one is a design constraint rather than a feature.
Working well on desktop as well as mobile browsers is the first, and it is the one that produces the legacy browser support in the project description. Broad browser support is not a nice-to-have here; it is a direct consequence of treating memory and initial payload as the scarce resources, because a client that pulls the whole timeline into memory is fine on a desktop and unusable on a phone.
The second goal, that UI components can be easily used in isolation, is about the component layer rather than the app. It means the parts of the interface are written so they can be picked up individually, which is what makes the embedding story plausible.
The third goal is the interesting one. Hydrogen is a standalone webapp, but can also be easily embedded into an existing website or webapp to add chat capabilities, and the readme points to the SDK instructions in doc/SDK.md for embedded usage. The repository layout backs this up with three separate Vite configurations, vite.config.js, vite.sdk-assets-config.js and vite.sdk-lib-config.js, and package scripts for build:sdk and watch:sdk that call scripts/sdk/build.sh. There is also a view-gallery.html at the root, which is the kind of file a component gallery ships with.
The fourth goal, deferred loading of unused parts after the initial page load, is the one that matters for the legacy browser case, where a large initial bundle is the difference between working and not working.
Running it locally with yarn and vite
The development environment is two commands. You run yarn install, only the first time, then yarn start in the terminal, and point the browser at http://localhost:3000.
There is a note about the toolchain that is easy to skim past. You need nodejs, and running yarn on top of any other js platform is not supported. The package manifest backs this up with an enginesStrict block requiring node >=15, and the start script is simply vite --port 3000, so the dev server is Vite with a fixed port.
If you would rather not set up node locally, the readme points to a docker directory with instructions in doc/docker.md, and the repository carries a Dockerfile-dev for that path.
The container build does the same work in two stages, building the app in a node alpine image and then serving the built output from an unprivileged nginx image:
FROM --platform=${BUILDPLATFORM} docker.io/node:alpine as builder
RUN apk add --no-cache git python3 build-base
WORKDIR /app
# Copy package.json and yarn.lock and install dependencies first to speed up subsequent builds
COPY package.json yarn.lock /app/
RUN yarn install
COPY . /app
RUN yarn buildThe manifest also shows how the project tests itself, which is a bit unusual. The test script runs impunity with the entry point at src/platform/web/main.js and src/platform/web/Platform.js, forcing ESM directories, over lib/ and src/ with the root directory at src/. There is a separate postcss test script, an sdk test that builds the SDK and then runs it in both an ESM Vite build environment and a CommonJS environment, and a test:app script that calls scripts/test-app.sh. Playwright is a dev dependency, with a playwright.config.ts and a playwright/ directory at the root, so the end to end layer is browser based.
Deploying a static build, and the caching trap in config.json
Hydrogen is deployed to hydrogen.element.io, and the readme also explains how to run it on your own web server. The steps are: download the latest release package, extract it to the public directory of the web server, and, on a first deploy, copy config.sample.json to config.json and make any modifications needed. The push section does not need changing unless you have set up your own sygnal instance.
The caching instruction is the part that will bite you. The server should disable caching entirely for index.html, for sw.js, for config.json, and for all theme manifests referenced in the themeManifests of config.json, which are typically called theme-{name}.json.
The reason is spelled out right after, and it is a good example of a service worker detail that surprises people. Those resources will still be cached client-side by the service worker, so you will still need to refresh the app twice before config.json changes are applied. The service worker holds a copy that the browser will not re-request, so a config change only lands after the second refresh.
The container path does something clever with the same file. The Dockerfile builds the app in a node stage, then, because the runtime image runs as an unprivileged user, it moves the default config into /config.json.bundled and symlinks target/config.json to /tmp/config.json, which is writable at runtime. A dynamic-config.sh script is installed into the docker entrypoint directory so the config can be supplied at container start, and the built app is copied into /usr/share/nginx/html of an nginx-unprivileged image.
Where it sits against Element Web, and the licensing split
The alternative to Hydrogen is not another Matrix client, it is Element Web, and the readme tells you that directly. Do not file feature requests to be on a par with Element Web. The difference is one of scope: Element Web is the full client, Hydrogen is a minimal one that does a smaller set of things while using less memory, running offline better and loading in browsers that Element Web does not target.
The practical difference in approach is the storage layer. Element Web keeps a lot of state in memory and relies on IndexedDB as a store, while Hydrogen is built so that as much as possible is offloaded to IndexedDB in the first place, which is why the package description names RAM usage as the thing it is trying to reduce.
The licensing is the part that needs a careful read, and it is a dual arrangement rather than a single grant. The software is multi licensed by New Vector Ltd, which is Element. It can be used either for free under the terms of the GNU Affero General Public License, either version 3 of the License or at your option any later version, or under the terms of a paid-for Element Commercial License agreement between you and Element, with terms that may vary depending on what you and Element have agreed.
So the AGPL-3.0 in the repository metadata is only one half. The repository carries both LICENSE-AGPL-3.0 and LICENSE-COMMERCIAL at the root, and the manifest license field says SEE LICENSE IN README.md, which is the accurate pointer. Copyright is split across three holders, OpenMarket Ltd for 2015 to 2016, The Matrix.org Foundation C.I.C. for 2019 to 2023, and New Vector Ltd for 2025.
The state of the repository, and the release question
The last push to the repository was on 2026-04-09, and the newest tagged release listed is v0.5.1 from 2024-10-21, with v0.5.0 from 2024-08-20 and v0.4.1 from 2023-09-04.
The gap between those two facts is the thing to be careful about. The repository is not archived and commits continue, but there has been no release since October 2024, and the project is explicitly described as a prototype in its own package description.
There is also a naming detail worth flagging. The repository is element-hq/hydrogen-web, while the readme directs you to the release packages published under vector-im/hydrogen-web, and the manifest still carries the repository URL of [email protected]:vector-im/hydrogen-web.git. The project has moved, and the documentation has not entirely caught up. If you are looking for the release artifacts, follow the readme's link rather than assuming the repository you are reading is the one that publishes them.
The repository layout shows the project's shape regardless. There is src/, a doc/ directory including the SDK instructions, docker/, scripts/ with an sdk/ subdirectory, prototypes/ for what is presumably exploratory work, playwright/ for browser tests, a TODO.md, a FAQ.md, and three Vite configs, which is the clearest summary of what Hydrogen is trying to be: an application, a component library, and an embeddable SDK, built from one codebase.
Editorial conclusion
Adopt Hydrogen if you need a Matrix client for a constrained environment, an embedded chat inside an existing product, or a browser matrix that includes old clients, since the whole design targets low memory use and offline behaviour. Do not adopt it if you need feature parity with Element Web, because the project says plainly that it is work in progress, not ready for primetime, and asks that feature requests not be filed. Before you deploy, read the licensing section carefully, because the software is multi licensed and the AGPL route and the paid commercial licence are genuinely different obligations, and check whether the Element-branded release package you plan to download still carries the same code as the hydrogen-web repository you are reading here.
Frequently asked questions
What is the Hydrogen Matrix client?
Hydrogen is a minimal Matrix chat client focused on performance, offline functionality and broad browser support, including legacy and mobile browsers. The package description calls it a prototype that tries to minimize RAM usage by offloading as much as possible to IndexedDB.
How do I run Hydrogen locally for development?
Run yarn install once, then yarn start, and point the browser at http://localhost:3000. The start script is vite --port 3000, the engine requirement is node >=15, and the readme notes that you need nodejs because running yarn on top of any other js platform is not supported.
Can Hydrogen be embedded in an existing website?
Yes. One of the stated goals is that it is a standalone webapp but can also be easily embedded into an existing website or webapp to add chat capabilities, and the readme points to the SDK instructions in doc/SDK.md. The repository carries separate Vite configs and build scripts for the SDK.
How is Hydrogen licensed?
It is multi licensed by New Vector Ltd, either for free under the GNU Affero General Public License version 3 or later, or under a paid-for Element Commercial License agreement whose terms may vary by agreement. The repository carries both LICENSE-AGPL-3.0 and LICENSE-COMMERCIAL, and the manifest points to the README for the licence text.
Why do config.json changes need two refreshes to take effect?
The server should disable caching for index.html, sw.js, config.json and the theme manifests, but those resources are still cached client-side by the service worker. The readme states that you will still need to refresh the app twice before config.json changes are applied.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/element-hq-hydrogen-web)Was this useful?