{"id":13422362,"url":"https://github.com/supermedium/aframe-react","last_synced_at":"2025-11-13T22:37:38.967Z","repository":{"id":38961661,"uuid":"48141141","full_name":"supermedium/aframe-react","owner":"supermedium","description":":atom: Build virtual reality experiences with A-Frame and React.","archived":false,"fork":false,"pushed_at":"2024-06-19T15:56:27.000Z","size":1309,"stargazers_count":1421,"open_issues_count":43,"forks_count":151,"subscribers_count":50,"default_branch":"master","last_synced_at":"2024-10-29T15:33:25.285Z","etag":null,"topics":["aframe","react","virtual-reality","vr","webvr"],"latest_commit_sha":null,"homepage":"https://ngokevin.github.io/aframe-react-boilerplate/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/supermedium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-16T23:33:37.000Z","updated_at":"2024-10-24T11:37:29.000Z","dependencies_parsed_at":"2024-06-18T13:38:11.201Z","dependency_job_id":"554f19a6-6b2e-46e1-9ec9-1bc7c9540f6b","html_url":"https://github.com/supermedium/aframe-react","commit_stats":{"total_commits":151,"total_committers":25,"mean_commits":6.04,"dds":0.2847682119205298,"last_synced_commit":"b5c064a6597dde8cf4a52aa6cbdf5911c158d83b"},"previous_names":["aframevr/aframe-react","ngokevin/aframe-react"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supermedium%2Faframe-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supermedium%2Faframe-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supermedium%2Faframe-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supermedium%2Faframe-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/supermedium","download_url":"https://codeload.github.com/supermedium/aframe-react/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248487733,"owners_count":21112188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aframe","react","virtual-reality","vr","webvr"],"created_at":"2024-07-30T23:00:42.715Z","updated_at":"2025-11-13T22:37:33.914Z","avatar_url":"https://github.com/supermedium.png","language":"JavaScript","readme":"\u003ch1 align=\"center\"\u003eaframe-react\u003c/h1\u003e\n\n\u003e I recommend using vanilla A-Frame and [aframe-state-component](https://npmjs.org/aframe-state-component) with [static templating](https://mozilla.github.io/nunjucks/) over `aframe-react`. React wastes a lot of cycles and incurs a lot of memory garbage. aframe-react is often abused where it is too easy to place 3D/real-time logic at the React layer, causing poor performance (e.g., doing React renders on ticks). aframe-react applications frequently ignore the prescribed ECS framework of A-Frame. Internally, React does tons of computation to compute what changed, and flushes it to the entire application. It is apparent React ecosystem does not care much about memory as most examples allocate functions and objects in the render method, and where immutables are popular. With only ~10ms per frame to do all computation, there is little room for React's massive system.\n\n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://cloud.githubusercontent.com/assets/674727/19173367/d6590832-8bdb-11e6-9336-658b00bc0460.png\" height=\"200\"\u003e\n\u003c/div\u003e\n\n\u003ch5 align=\"center\"\u003e\n  Build virtual reality experiences with \u003cb\u003e\u003ca href=\"https://aframe.io\"\u003eA-Frame\u003c/a\u003e\u003c/b\u003e and \u003cb\u003e\u003ca href=\"https://facebook.github.io/react/\"\u003eReact\u003c/a\u003e\u003c/b\u003e.\n\u003c/h5\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.org/package/aframe-react\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/aframe-react.svg?style=\"flat-square\" alt=\"npm\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://npmjs.org/package/aframe-react\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dt/aframe-react.svg?style=flat-square\" alt=\"npm\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://travis-ci.org/aframevr/aframe-react\"\u003e\n    \u003cimg src=\"https://secure.travis-ci.org/aframevr/aframe-react.svg?branch=master\" alt=\"Travis CI\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://npmjs.com/package/aframe-react\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/l/aframe-react.svg?style=flat-square\" alt=\"License\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n## Examples\n\n\u003ca href=\"http://360syria.com\"\u003e\n\u003cimg width=\"320\" alt=\"Fear of the Sky by Amnesty International UK\" src=\"https://cloud.githubusercontent.com/assets/674727/19344336/a5830bbe-90ee-11e6-9f68-2c23a9be4e95.png\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://www.youtube.com/watch?v=japz3zoi8gw\u0026feature=youtu.be\"\u003e\n\u003cimg width=\"320\" height=\"171\" alt=\"Snowboards\" src=\"https://cloud.githubusercontent.com/assets/674727/24980264/587ded8e-1f8c-11e7-874e-c29264586cd6.png\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/michaltakac/mathworldvr\"\u003e\n\u003cimg width=\"320\" alt=\"MathworldVR\" src=\"https://cloud.githubusercontent.com/assets/674727/25073541/c42e1b12-229d-11e7-946f-02e7e98d2b9f.jpg\"\u003e\n\u003c/a\u003e\n\n## Installation\n\nInstall with [npm](https://www.npmjs.com/package/aframe-react) or\n[yarn](https://github.com/yarnpkg/yarn).\n\n```\nnpm install --save aframe aframe-react react react-dom\nyarn add aframe aframe-react react react-dom\n```\n\n## Example\n\n```js\nimport 'aframe';\nimport 'aframe-particle-system-component';\nimport {Entity, Scene} from 'aframe-react';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nclass VRScene extends React.Component {\n  render () {\n    return (\n      \u003cScene\u003e\n        \u003cEntity geometry={{primitive: 'box'}} material={{color: 'red'}} position={{x: 0, y: 0, z: -5}}/\u003e\n        \u003cEntity particle-system={{preset: 'snow'}}/\u003e\n        \u003cEntity light={{type: 'point'}}/\u003e\n        \u003cEntity gltf-model={{src: 'virtualcity.gltf'}}/\u003e\n        \u003cEntity text={{value: 'Hello, WebVR!'}}/\u003e\n      \u003c/Scene\u003e\n    );\n  }\n}\n\nReactDOM.render(\u003cVRScene/\u003e, document.querySelector('#sceneContainer'));\n```\n\nSee [aframe-react-boilerplate](https://github.com/ngokevin/aframe-react-boilerplate)\nfor a basic example.\n\n## Introduction\n\n![A-Frame](https://cloud.githubusercontent.com/assets/674727/24384472/e833ccee-1318-11e7-81a5-61e782f5b472.png)\n\n[A-Frame](https://aframe.io) is a web framework for building virtual reality\nexperiences. Since A-Frame is built on top of the DOM, web libraries such as\nReact, Vue.js, Angular, Ember.js, d3.js are able to sit cleanly on top of\nA-Frame.\n\nA-Frame is an [entity-component-system (ECS) framework exposed through\nHTML](https://aframe.io/docs/). ECS is a pattern used in game development that\nfavors composability over inheritance, which is more naturally suited to 3D\nscenes where objects are built of complex appearance, behavior, and\nfunctionality. In A-Frame, HTML attributes map to *components* which are\ncomposable modules that are plugged into `\u003ca-entity\u003e`s to attach appearance,\nbehavior, and functionality.\n\nReleased on the same day as A-Frame, `aframe-react` is a very thin layer on top\nof A-Frame to bridge with React. `aframe-react` passes React props to directly\nA-Frame using refs and `.setAttribute()`, bypassing the DOM. This works since\nA-Frame's `.setAttribute()`s are able to take non-string data such as objects,\narrays, or elements and synchronously modify underlying 3D scene graph.\n\n```js\n// aframe-react's \u003cEntity/\u003e React Component\n\u003cEntity geometry={{primitive: 'box', width: 5}} position=\"0 0 -5\"/\u003e\n\n// renders\n\u003ca-entity\u003e\n\n// and then applies the data directly to the underlying 3D scene graph, bypassing the DOM.\n\u003ca-entity\u003e.setAttribute('geometry', {primitive: 'box', width: 5});\n\u003ca-entity\u003e.setAttribute('position', '0 0 -5');\n```\n\n`aframe-react` provides the best of both worlds between A-Frame and React, the\n3D and VR-oriented entity-component architecture of A-Frame, and the view and\nstate management ergonomics of React, without penalties of attempting to use\nReact for a VR application.\n\n## Making React Viable\n\nA-Frame and `aframe-react` gives some viability for React to use in VR\napplications. The value proposition of React is limited to the 2D Web:\n\n- Improve rendering performance for 2D web pages by reducing calls to the\n  browser's 2D layout engine via the virtual DOM.\n- Provide an predictable application structure for large 2D web applications through\n  a structured nesting of React components, data binding, and one-way data flow.\n\nHowever, these propositions fall short in 3D and VR applications:\n\n- In 3D and VR applications, including A-Frame, the 2D browser layout engine is\n  not touched. Thus React's reconciliation engine can become an unpredictable\n  performance liability for little benefit.\n- In 3D and VR applications, objects are not structured in a top-down hierarchy like\n  2D web applications. 3D objects can exist anywhere and interact with any other 3D object\n  in a many-to-many manner. But React's paradigm prescribes data flow from parent-to-child,\n  which makes it restrictive for 3D and VR applications.\n\nA-Frame and aframe-react gives meaning and purpose to React: **A-Frame provides\nan actual DOM for React to reconcile, diff, and bind to**.\n\nReact also raises questions around performance; React is a very large library\ndesigned for a 60fps 2D Web, is it equipped to handle 90fps VR applications?\n90 prop updates per second per object for many objects through React's engine\ncauses concern in the overhead added for each operation.\n\naframe-react lets A-Frame handle the heavy lifting 3D and VR rendering and\nbehavior. A-Frame is optimized from the ground up for WebVR with a 3D-oriented\nentity-component architecture. And **aframe-react lets React focus on what it's\ngood at: views, state management, and data binding.**\n\n### Entity-Component Meets React\n\nA-Frame's entity-component-system (ECS) pattern is tailored for 3D and VR\napplications. What React did for 2D web applications is what ECS did for 3D\napplications in terms of providing a useful abstraction. ECS promotes\ncomposability over hierarchy. In 3D applications, composability refers to\ncomposition of appearance, behavior, and logic rather than having fixed blocks.\nThis lets us do things like define a flying robot that explodes on contact and\nmakes robot sounds by snapping together a pre-existing model component, explode\ncomponent, event handler component, sound component, and flying component.\n\nUnfortunately, React (and the 2D web for that matter) is heavily hierarchical,\nwhich is not suited for 3D. Whereas 2D web development consisted of structuring\nand laying out from an assorted set of fixed 2D elements (e.g., `\u003cp\u003e`, `\u003ca\u003e`,\n`\u003cimg\u003e`, `\u003cform\u003e`), 3D development involves objects that are infinite in\ncomplexity and type. ECS provides an easy way of defining those objects by\nmixing and matching plug-and-play components.\n\nWith aframe-react, we get the best of both worlds. The 3D and VR architecture\nof A-Frame, and the view and state ergonomics of React. React can be used to\nbind application and state data to the values of A-Frame components. And we\nstill have access to all the features and performance of A-Frame as well as\n[A-Frame's community component ecosystem](https://aframe.io/registry/).\n\n## API\n\n`aframe-react`'s API is very thin on top of A-Frame, less than 200 lines of\nsource code. The API consists of just two React Components: `\u003cEntity/\u003e` and\n`\u003cScene/\u003e`.\n\n#### \\\u003cEntity {...components}/\u003e\n\n`\u003cEntity/\u003e` wraps\n[`\u003ca-entity\u003e`](https://aframe.io/docs/0.5.0/core/entity.html), the *entity*\npiece of the [entity-component-system\npattern](https://aframe.io/docs/0.5.0/core/). Plug in [A-Frame\ncomponents](https://aframe.io/docs/0.5.0/introduction/#entity-component-system)\nas React props to attach appearance, behavior, or functionality to the\n`\u003cEntity/\u003e`.\n\n```jsx\n\u003cScene\u003e\n  \u003cEntity\n    geometry={{primitive: 'box', width: 5}}\n    material={{color: red, roughness: 0.5, src: texture.png}}\n    scale={{x: 2, y: 2, z: 2}}\n    position={{x: 0, y: 0, z: -5}}/\u003e\n\u003c/Scene\u003e\n```\n\n[Community A-Frame components](https://aframe.io/registry/) can be imported and\ninstalled through npm:\n\n```\nimport 'aframe-particle-system-component';\nimport 'aframe-mountain-component';\n\n// ...\n\n\u003cScene\u003e\n  \u003cEntity mountain/\u003e\n  \u003cEntity particle-system={{preset: 'snow', particleCount: 5000}}/\u003e\n\u003c/Scene\u003e\n```\n\n#### `primitive`\n\nTo use A-Frame [primitives](https://aframe.io/docs/0.5.0/primitives/), provide\nthe `primitive` prop with the primitive's element name (e.g., `a-sphere`).\nMappings can be applied the same as in HTML through React props:\n\n```jsx\n\u003cEntity primitive='a-box' color=\"red\" position=\"0 0 -5\"/\u003e\n\u003cEntity primitive='a-sphere' color=\"green\" position=\"-2 0 -3\"/\u003e\n\u003cEntity primitive='a-cylinder' color=\"blue\" position=\"2 0 -3\"/\u003e\n\u003cEntity primitive='a-sky' src=\"sechelt.jpg\"/\u003e\n```\n\n#### `events`\n\nTo register event handlers, use the `events` prop. `events` takes a mapping of\nevent names to event handler(s). Multiple event handlers can be provided for a\nsingle event name by providing an array of functions. Try not to pass in inline\nfunctions to not trigger unnecessary React renders. Pass in binded functions\ninstead.\n\nFor example, using the synthetic `click` event provided by A-Frame's `cursor`\ncomponent, or a `collided` event possibly provided by a physics component.\n\n```jsx\nhandleClick = () =\u003e {\n  console.log('Clicked!');\n}\n\nhandleCollide = () =\u003e {\n  console.log('Collided!');\n}\n\nrender() {\n  return (\n    \u003cScene\u003e\n      \u003cEntity events={{\n        click: this.handleClick,\n        collided: [this.handleCollide]}}/\u003e\n    \u003c/Scene\u003e\n  );\n}\n```\n\n`aframe-react` does not support React-style `onXXX` event handlers (e.g.,\n`onClick`). Unlike 2D web pages, VR sites are composed entirely of custom\nsynthetic event names (which could have hyphens, be all lowercase, be\ncamelCase, all uppercase, camel case, etc.,). The possible event names are\ninfinite. The `events` prop makes it explicit what the event names to handle\nare.\n\n#### `_ref`\n\nUse `aframe-react`'s `_ref` prop to add a callback to the underlying\n`\u003ca-entity\u003e` DOM node:\n\n```\n\u003cEntity _ref={this.entityCallback}/\u003e\n```\n\n#### \\\u003cScene {...components}/\u003e\n\n`\u003cScene/\u003e` extends `\u003cEntity/\u003e` and renders `\u003ca-scene\u003e` instead of `\u003ca-entity\u003e`.\nPlace all `\u003cEntity/\u003e`s as a child of the `\u003cScene/\u003e` Component. There should\nonly be one `\u003cScene/\u003e` per page:\n\n```jsx\n\u003cScene\u003e\n  \u003cEntity/\u003e\n\u003c/Scene\u003e\n```\n\n## Best Practices\n\nLet A-Frame and three.js handle the heavy lifting of 3D rendering and behavior,\nand delegate React to what it was meant for: views, state management, and data\nbinding.\n\nFor example, don't create `requestAnimationFrame`s to continuously throw React\nprop updates to A-Frame. Instead, create an A-Frame component with a tick\nhandler such that everything is done in memory with little overhead. Do however\nuse React to set up initial state and data binding that might configure that\nA-Frame component.\n\n## Using with Preact\n\n`aframe-react` works with Preact. Since `aframe-react` uses `React.Component`,\nwe have to tell Webpack to alias that to `Preact.Component`:\n\n```\nresolve: {\n  alias: {\n    react: 'preact'\n  }\n}\n```\n","funding_links":[],"categories":["UI Frameworks","Projects","Web-Based Frameworks","JavaScript"],"sub_categories":["Component Collections","Motion Controllers inside Unity!"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupermedium%2Faframe-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsupermedium%2Faframe-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupermedium%2Faframe-react/lists"}