Hubs: the open source client behind Mozilla's WebXR meeting rooms
Duck-themed multi-user virtual spaces in WebVR. Built with A-Frame.
At a glance
- What is it?
- Hubs is the A-Frame and Three.js client for the Hubs 3D collaboration platform. It is a front end, not a server, and the README is honest about the three other repositories you need before anything appears in a browser.
- Who is it for?
- Hubs is worth reading if you want to build spatial interfaces rather than run a meeting service, since the client, the networked scene layer and the ops tooling are all public under MPL 2.0 and the A-Frame structure is legible. It is the wrong tool if you need turnkey self hosting, because the README sends you to Hubs Community Edition for that, and it is the wrong tool if your audience is on desktop browsers without WebXR, since the spatial view is the product.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 61 days ago.
- What is it written in?
- Mainly JavaScript, 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 client repository, not a platform you can install
The first line of the README settles the most common misunderstanding about this project: what lives here is the client-side code for Hubs, described as an online 3D collaboration platform that works for desktop, mobile and VR. The description field on both the repository and package.json still reads as duck-themed multi-user virtual spaces in WebVR, built with A-Frame, which is a leftover from the project's Mozilla era and does not describe what a user sees today. The package.json entry point is src/index.js, and the tree is a JavaScript application with webpack, Babel, TypeScript checking and an ava test runner rather than a service you deploy and forget.
That split matters for anyone evaluating it. There is no server here, no database and no authentication backend. If you arrive expecting to run a private 3D chat server, you will read the README to the end without finding one command that starts it.
Running the client locally with npm ci and npm run dev
The quick start is five lines, and the only unusual requirement is a Node version. The README says the build servers use 16.16.0 and suggests NVM if you juggle several JavaScript projects, which is a reasonable suggestion given how many versions of Node this application has spanned.
git clone https://github.com/Hubs-Foundation/hubs.git
cd hubs
# nvm use v16.16.0 # if using NVM
npm ci
npm run dev`npm run dev` is not a stub. In package.json it maps to `webpack serve --mode=development --env remoteDev=1 --progress`, so it starts a webpack development server that points the client at development builds of the backend rather than anything on your machine. There is also `npm run local` for `localDev=1` and `npm run start` for a run with app config loaded. The presence of `bundle-analyzer`, `stats`, `spritesheet` and `doc` scripts tells you this is treated as a real front-end codebase with performance and documentation tooling, not a demo.
One caution about `npm ci` here: the repository ships a package-lock.json, so a lockfile install is the correct choice, and the release history shows the maintainers actively aligning dependency versions rather than letting transitive packages drift.
Why hubs.local and a self-signed certificate are mandatory
The most useful detail in the README is the one that saves an afternoon. The backend dev server is configured with CORS to accept connections only from hubs.local:8080, so you have to point a browser at that hostname rather than at localhost. Two entries in the local hosts file do it:
127.0.0.1 hubs.local
127.0.0.1 hubs-proxy.localThen you open https://hubs.local:8080 and accept the warning for the self-signed certificate, because HTTPS is required. Two details there are easy to miss: the scheme is https rather than http, and the host is hubs.local rather than the more obvious hubs-proxy.local, which is why both entries are needed.
The README also flags a limitation that shapes the whole local development story. Running the client locally still connects you to the development versions of the Reticulum server, and that server does not allow access from outside localhost. So a local Hubs client is not a private instance. Getting one of those means a different repository entirely.
The three dependencies the README names out loud
Hubs is a client, so the interesting engineering sits in the pieces around it. The README lists them under additional resources and they are worth reading in order, because each one answers a question the client cannot.
Reticulum is the Phoenix-based backend for managing state and presence, which is where avatars, room membership and the object graph actually live. Networked A-Frame is the layer that synchronizes scene entities between peers, so it is the piece to read if you care about how two users see the same room converge. Hubs-Ops is infrastructure as code and management tools for running the backend services on AWS, which is the answer to how the hosted service is operated.
This is an unusually clear dependency structure for a project people meet through a URL. It also means the client's own tree gives limited insight into persistence or transport, and readers looking for a self-hosted stack will find nothing in src/ about either.
What the release tags reveal about how this ships
Releases are published as dated prod tags rather than semantic versions, and the recent ones are informative. prod-2026-03-11, published on 2026-03-12, contains a single change: a fix for PDF page advance not working in mobile VR. prod-2025-12-17 is a broader maintenance release covering dependency alignment for the ajv subdependency, disabling scheduled Browserstack testing, a pre-commit hook that runs automated tests and fixes lint errors, and work on the scene user interface. prod-2025-06-19 shipped a bump of the Docker container to Node 22 alongside fixes for chat grouping and an arm64 build dependency.
Two patterns stand out. Platform upkeep is part of the product work, since the Node version moves and arm64 support needed a phantomjs fix. And the testing story has been tightening, with the pre-commit hook and the storybook update landing in the same release.
The last push was on 2026-08-23, and the repository is not archived. Worth noting is that prod-2026-03-11 is the most recent published release while pushes have continued since, so the tag stream runs behind the branch.
Custom clients, localization, and the limits of this repository
The README offers three distinct paths, and telling them apart is the practical way to use this project. To run Hubs on your own servers, go to Hubs Community Edition in the hubs-cloud repository. To deploy a custom client to an existing Hubs Cloud instance, follow the custom clients guide. To contribute to the main fork, read CONTRIBUTING.md. To modify the client for your own purposes, continue with the quick start.
Contribution comes with enforced checks. A git hook runs before each commit to lint and test, the same checks run in CI, and `npm run test` runs them on demand. In unusual situations you can suppress the hook with the `-n` flag on commit. The tree shows the supporting configuration: eslint.config.js, .stylelintrc, .htmlhintrc, .prettierrc.json, a Jenkinsfile, a Storybook setup and a doc directory.
Localization is called out as an area where help is wanted, with its own documentation under src/assets/locales. The presence of themes.json and REMIXING.md suggests the visual layer is meant to be restyled rather than forked, and PRIVACY.md, TERMS.md and SECURITY.md at the root indicate this repository also carries the governance documents for the wider service.
Editorial conclusion
Hubs is worth reading if you want to build spatial interfaces rather than run a meeting service, since the client, the networked scene layer and the ops tooling are all public under MPL 2.0 and the A-Frame structure is legible. It is the wrong tool if you need turnkey self hosting, because the README sends you to Hubs Community Edition for that, and it is the wrong tool if your audience is on desktop browsers without WebXR, since the spatial view is the product. Start at the quick start in the README, keep the defaults for the local hosts file, and read package.json before you touch themes.json.
Frequently asked questions
Do I need a backend to run the Hubs client locally?
Not one that lives in this repository. The client connects to the development versions of the Reticulum server, which the README says cannot be reached from outside localhost. Self hosting is handled by Hubs Community Edition in the hubs-cloud repository.
What does the Hubs client do when the browser has no WebXR support?
The README describes the platform as working for desktop, mobile and VR, so a desktop view exists alongside the VR path. The spatial 3D scene remains the interface on every platform, which is the part that depends on A-Frame and Three.js rendering rather than a headset.
Why does the local Hubs build fail to connect until I edit my hosts file?
The backend dev server is configured with CORS to accept only connections from hubs.local:8080. Adding hubs.local and hubs-proxy.local to your hosts file, then opening https://hubs.local:8080 and accepting the self-signed certificate, satisfies that restriction.
What license is the Hubs client under?
Mozilla Public License 2.0, stated in the README, in package.json and in the LICENSE file at the root of the repository. MPL 2.0 is a file-level copyleft license, so modifications to covered files carry obligations when you distribute them.
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/hubs-foundation-hubs)Was this useful?