# A-Frame: building browser based 3D, AR and VR scenes from HTML

> A-Frame is an MIT licensed JavaScript framework that wraps three.js in an entity-component architecture and lets you declare a WebXR scene with HTML tags. It suits web developers who want a headset experience without learning a 3D engine first.

**aframevr/aframe** — :a: Web framework for building virtual reality experiences.

- Repository: https://github.com/aframevr/aframe
- Website: https://aframe.io/
- Stars: 17,646 · Forks: 4,399
- Language: JavaScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/aframevr-aframe

## The problem A-Frame removes: WebXR boilerplate

Getting a WebXR session running means handling renderer setup, camera rigs, controller tracking, resize and device switching before anything appears on screen. A-Frame's stated purpose is to absorb that work: the README says it handles "the 3D and WebXR boilerplate required to get running across platforms including mobile, desktop, and all headsets (compatible with a WebXR capable browser)" as soon as you drop in an a-scene element. The audience the project names is broad on purpose: web developers, VR and AR enthusiasts, educators, artists, makers and kids. That is a real design constraint rather than marketing. A scene is valid HTML, so it can be copied, pasted and edited by someone who has never opened a 3D editor. The trade-off is that anything you cannot express as an element or a component attribute falls back to JavaScript, and the framework does not hide three.js from you once you go there.

## Entity-component architecture on top of three.js

A-Frame is not a renderer of its own. The README describes it as "a thin framework on top of three.js", and the package metadata points main at ./dist/aframe-master.js with an ES module build at ./dist/aframe-master.module.min.js. The abstraction it adds is an entity-component system. An a-entity is an empty object in the scene graph; components are the data attached to it. In the README's community example, one entity carries particle-system, another carries geometry, material, position, light and animation attributes side by side. Each attribute name maps to a registered component and each value string is parsed into that component's schema, which is why semicolons separate properties inside a single attribute value. This is what makes third party plugins composable: a particle system, a physics engine or an ocean shader registers itself as a component and becomes an attribute you can type in markup. The README also claims the framework does not touch the browser layout engine despite using the DOM, and that performance is a stated priority. That claim is the project's own; the repository does not publish benchmark numbers alongside it.

## Installing A-Frame and rendering a first scene

The README's quickest path is a script tag pointing at a versioned release build, which is what the starter example uses. There is no build step and no bundler: the file defines the custom elements, and the browser renders the scene when it parses the body.

```html
<html>
  <head>
    <script src="https://aframe.io/releases/1.8.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
      <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
      <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
      <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>
```

Save that as an HTML file and open it over http rather than from the filesystem, since WebXR and many asset loads assume a real origin. You should see four coloured primitives on a light grey background, with a headset icon in the corner if a WebXR device is available. Note that a-plane is rotated -90 degrees on X to lie flat as a floor; a-sky is the background sphere.

For local development the repository ships a webpack dev server instead. Running npm install followed by npm start invokes the dev script, which serves on port 8080, and npm run docs serves the documentation directory on port 9001. Community components are loaded the same way as the core build, as separate script tags before the scene, and are then used as attributes.

```html
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-particle-system-component@1.2.x/dist/aframe-particle-system-component.min.js"></script>
<a-entity id="rain" particle-system="preset: rain; color: #24CAFF; particleCount: 5000"></a-entity>
```

Those two lines come from the README's community components example and show the pattern: a script tag registers the component, then the attribute name matches the component name.

## Where A-Frame is the wrong tool

The framework's portability is also its ceiling. A scene runs in a WebXR capable browser and nowhere else, so a native headset store build is out of scope; the README frames compatibility entirely in terms of browsers and headsets that support WebXR. Anything requiring a native SDK, platform specific input APIs or an offline store submission needs a different stack. The second constraint is authoring. A-Frame's visual inspector opens on any scene with ctrl + alt + i and is described as having a workflow similar to browser developer tools, but it is an inspection and tweaking surface, not the source of truth. If your team wants a scene graph saved as an editor project file, A-Frame will feel backwards: markup is the project. Third, community components are separate packages with their own release cadence, and the README pins them by version in the CDN path precisely because they move independently of the core. A component that has not been updated for your A-Frame version is your problem to resolve, not the framework's. Finally, the README does not document a rollback procedure for a bad release upgrade, so pinning the release URL is the practical safeguard rather than a documented downgrade path.

## A-Frame against Babylon.js and plain three.js

The closest comparison in this space is Babylon.js, which is a full 3D engine with its own scene graph, material system, physics integration and editor, aimed at application development rather than document markup. The difference in approach is where the scene lives. In A-Frame the scene is an HTML document and entities are elements, so a CMS, a static site or a server rendered page can emit a scene as markup. In Babylon.js the scene is constructed in JavaScript against an engine API, which gives finer control over the render loop and asset pipeline but means the scene is code, not a document. Plain three.js sits underneath A-Frame, and the README is explicit that A-Frame developers retain "unlimited access to JavaScript, DOM APIs, three.js, WebXR, and WebGL". Choosing three.js directly buys you the smallest possible abstraction and total control; choosing A-Frame buys you the entity-component layer and the HTML surface at the cost of an extra indirection between your intent and the renderer. If your team already has three.js code and no interest in markup, adding A-Frame is overhead. If your team has web pages and no 3D experience, A-Frame is the shorter path.

## Maintenance, versioning and the MIT licence

The repository is not archived and the last push was on 2026-07-13, roughly two months before this article, so it is reasonable to describe the project as receiving changes. The most recent release listed is v1.8.0 on 2026-06-24, following v1.7.1 in April 2025 and v1.7.0 in February 2025. That cadence matters for planning: minor releases have arrived at intervals of a year or more, so an upgrade is a deliberate event rather than a background chore. The release script in package.json shows the maintainers run a prerelease step that rewrites version references, which is a hint that release URLs and documentation paths are versioned and should be pinned rather than floated. A-Frame is MIT licensed, which permits commercial and closed source use and modification provided the copyright notice and permission notice are preserved; the repository carries a LICENSE file at the top level. That is a description of the licence text, not legal advice, and obligations around bundled assets or vendored code should be checked with whoever handles licensing on your side. The upgrade cost itself is mostly the community component set: core changes are documented in the changelog, but every third party component you load has to be compatible with the core version you move to.

## Conclusion

Adopt A-Frame if your team already writes JavaScript and HTML and you need a scene that runs in a WebXR capable browser on desktop, phone and headset from one file. Do not adopt it if you need native store builds or a visual editor as the primary authoring surface, since the inspector is a debugging tool rather than a project format. Before committing, open the versioned release script URL you intend to pin, confirm the WebXR support of the browsers you must ship to, and check that the community components you depend on are published for the A-Frame version you chose.

## FAQ

### What is A-Frame?

It is a JavaScript web framework for building browser based 3D, AR and VR experiences, described in its README as a thin framework on top of three.js. Scenes are declared in HTML using custom elements such as a-scene, a-box and a-sky.

### How do you install A-Frame?

The README's starter example loads a versioned release build directly with a script tag pointing at https://aframe.io/releases/1.8.0/aframe.min.js, with no build step required. For local development the repository also provides an npm dev server on port 8080.

### How do you use A-Frame to build a scene?

You write an a-scene element and place entities inside it, setting components as attributes such as position, rotation, color, geometry and material. Community components are loaded as additional script tags and then used as attributes on entities.

## Sources

- [aframevr/aframe on GitHub](https://github.com/aframevr/aframe)
- [License: MIT](https://github.com/aframevr/aframe/blob/master/LICENSE)
- [Project website](https://aframe.io/)
- [README](https://github.com/aframevr/aframe/blob/master/README.md)
- [Releases](https://github.com/aframevr/aframe/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aframevr-aframe
