AR.js: marker, image and location AR in the browser
Image tracking, Location Based AR, Marker tracking. All on the Web.
At a glance
- What is it?
- AR.js is an MIT-licensed JavaScript library that adds marker tracking, image tracking and GPS-anchored content to A-Frame or three.js scenes. It is a good fit when the scene already lives on the web and the target is a printed marker, and a poor fit when you need surface detection or face tracking.
- Who is it for?
- Adopt AR.js when your AR content is a printed marker, a trained image or a GPS coordinate and the rest of your product is already a web page. Do not adopt it for surface detection, occlusion or face tracking, because the library does not provide them.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 101 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 September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What AR.js solves, and for whom
The library targets a narrow but common problem: putting AR content into a page that is already a web page. There is no app store submission, no native SDK, no separate build target for iOS and Android. The README describes AR.js as "a lightweight library for Augmented Reality on the Web, coming with features like Image Tracking, Location-based AR and Marker tracking." That sentence is also the boundary of the feature set. Three tracking modes, nothing else.
The audience follows from that. It suits web developers who can write HTML and a little JavaScript and who already have a three.js or A-Frame scene. It suits people who need a printed target, such as a product card, a poster, a sticker or a page in a book. It suits location experiences where content is anchored to a latitude and longitude rather than to a visual feature. It does not suit teams who need the camera to understand an arbitrary room. The README's own update note points readers who need image tracking and face tracking toward MindAR, and adds that "as for now, AR.js is still the only library providing Marker based and Location based AR features." That is the maintainers' framing, not an independent benchmark, but it explains the project's position accurately enough: the niche is markers and coordinates.
How the tracking pipeline is wired
The repository is a build system around two consumers of the same core. The top level holds aframe/ and three.js/ directories, and webpack.config.js drives the bundling. The package.json declares @ar-js-org/artoolkit5-js, aframe and three as dependencies, so the tracking math comes from artoolkit5-js while the rendering comes from whichever framework you picked. AR.js itself is mostly glue: camera access, the video texture, the pose from the tracker, and the mapping of that pose onto an A-Frame entity or a three.js object.
The README is explicit that the builds are exclusive. There are two A-Frame builds and three three.js builds, and you import the one you need, not both. The A-Frame pair is aframe-ar-nft.js for image tracking plus location, and aframe-ar.js for marker tracking plus location. On the three.js side, ar-threex.js covers image and marker tracking, ar.js exposes the ARjs namespace, and ar-threex-location-only.js is location only. The split exists because each build carries only the tracker code its mode needs.
Location tracking works differently from the other two. There is no computer vision involved. The README's geo example uses a-camera with gps-camera and rotation-reader, and positions content with gps-entity-place taking latitude and longitude. The camera's position comes from the device GPS and orientation sensors, and the scene places entities relative to that. This is why the geo example can show text that faces the viewer from a fixed coordinate, and why it degrades wherever GPS is weak.
Installing AR.js and running a first marker scene
There is no package install step for the browser case. The README distributes the builds as script tags from raw.githack.com, and the npm package name is @ar-js-org/ar.js with main pointing at ./aframe/build/aframe-ar.js. The README also shows how to pin a version by replacing the master segment of the URL with a tag:
<script src="https://raw.githack.com/AR-js-org/AR.js/3.4.8/aframe/build/aframe-ar-nft.js">That is the whole installation for a page. Note that the repository's own test script is a stub: package.json defines "test" as an echo that exits with an error, so there is no test suite to run after cloning. The npm scripts that do something are build, build:dev, server and the prettier format targets.
If you are working from a clone rather than the CDN builds, the scripts are:
npm install
npm run build
npm run serverThe build runs webpack in production mode, and server starts npx http-server -c -1, which serves the working directory on a local port with caching disabled. That last flag matters during development, because a cached AR build is a confusing thing to debug.
The README's image tracking example is the shortest path to a working scene. It loads A-Frame, then the NFT build, then declares an a-nft element with a url pointing at an image descriptor set, plus a gltf-model child. The scene element carries the tracking configuration:
<a-scene
vr-mode-ui="enabled: false;"
renderer="logarithmicDepthBuffer: true; precision: medium;"
embedded
arjs="trackingMethod: best; sourceType: webcam;debugUIEnabled: false;"
>The README's steps are to create the project, run it on a server, open the site on your phone, and scan the supplied trex picture. Two details in the example deserve attention before you copy it. The descriptor URL and the gltf-model URL are both prefixed with "your-server/" and the comment says you need to set up your server, because the example routes those requests through a CORS proxy. And the a-nft element carries smooth, smoothCount, smoothTolerance and smoothThreshold attributes, which the README does not explain; they control pose smoothing and you will have to read the official documentation to tune them.
For a marker scene, the mechanics are the same but the target is a printed marker image rather than a trained descriptor set, and the build is aframe-ar.js instead of aframe-ar-nft.js. The README links a live example and a picture to scan rather than repeating the markup.
Where AR.js stops being the right tool
The most concrete limitation is that the tracking modes are the product. If your experience depends on knowing where the floor is, AR.js cannot tell you. There is no plane detection, no depth, no occlusion, no anchoring to a surface the user picks. Marker and image tracking both answer a narrower question: where is this known target in the camera frame. Location tracking answers where the device is on the planet, with the accuracy the GPS gives you. Anything outside those questions is your problem.
Image tracking has a preparation cost that marker tracking does not. The a-nft element points at a descriptor set rather than at the JPEG itself, which means the image has to be processed into the descriptor files before the scene can use it. The README ships a pre-trained trex example and does not walk through the training step here. That step lives in the official documentation. Budget for it: a low-contrast or repetitive image trains badly, and you will not find that out until you are standing in front of it with a phone.
The location mode has its own failure surface. It reads GPS and device orientation, so it is only as good as the sensor fix and the compass. Indoors, in a city canyon, or on a device with a poorly calibrated magnetometer, placed content drifts or spins. The README's geo example is honest about the intended effect: the text appears in the requested position and keeps facing you as you move. That is a demonstration of the coordinate mapping, not a claim about positional accuracy.
There is also a maintenance signal worth reading plainly. The last push to the default branch was on 2026-06-21, and the most recent release listed is 3.4.8 from 2026-03-16. The repository is not archived. The README itself notes that the project changed hands, from its creator to Nicolò Carpignoli, and is now maintained by the AR.js org.
AR.js against MindAR and against plain WebXR
The README names the alternative itself. MindAR is described there as a separate open source web AR library, recommended for image tracking, including multiple images, and for face tracking. The difference in approach is visible in that sentence: MindAR's strength is the tracking mode AR.js does not have, faces, and multi-image tracking. If your project is a face filter or needs several images tracked at once, AR.js is the wrong starting point and the README says so.
The comparison against raw WebXR is a different axis. WebXR is a browser API, not a library, and it is what you would use if you wanted to build the tracking yourself or lean on the device's native AR capabilities. AR.js does not depend on WebXR for its tracking; it does its own vision work through artoolkit5-js and reads GPS and orientation sensors for the location mode. That is why it runs in browsers and on devices where WebXR AR is unavailable. The trade is that you inherit artoolkit's constraints, and you get markers and coordinates rather than the surface understanding a native AR runtime provides.
A-Frame and three.js are not alternatives to AR.js so much as the layer beneath it. The README ships builds for both, and package.json lists both as dependencies. Choosing between them is choosing your scene graph, not choosing your tracker.
Licence, upgrade cost and what a version bump means
The licence is MIT, stated in package.json and in the LICENSE file at the repository root. In practical terms that is a permissive licence, and the usual obligations attach: keep the copyright notice and the licence text with the distribution. This is not legal advice, and if you are embedding the library in a product with its own licensing constraints, that is a question for your own counsel.
Upgrading is cheap if you load the builds from a CDN, because the version is in the URL. The README shows the pattern: replace master with a tag such as 3.4.8. That also means you can pin and forget, which is the safer default for a production page. The release cadence visible in the repository is uneven. 3.4.6 landed on 2024-12-22, 3.4.7 on 2025-02-07, and 3.4.8 on 2026-03-16, about thirteen months later. There is a CHANGELOG.md at the root, and HOW_TO_RELEASE.md documents the release process for maintainers.
If you build from source instead, the upgrade cost is the webpack toolchain. The devDependencies pin webpack 5, webpack-cli 7 and worker-loader 3, and there are simple-git-hooks and lint-staged configured for a pre-commit prettier run. A major bump in any of those is your problem to absorb, not the library's.
Editorial conclusion
Adopt AR.js when your AR content is a printed marker, a trained image or a GPS coordinate and the rest of your product is already a web page. Do not adopt it for surface detection, occlusion or face tracking, because the library does not provide them. Before committing, verify two things on a real phone: that your server serves the .fset and .fset3 descriptor files next to the image, and that the marker or image still locks at the distance and angle your users will actually hold the camera.
Frequently asked questions
How do I use AR.js in an HTML page?
Load A-Frame, then one of the AR.js builds, then declare a scene with the arjs attribute and a target element such as a-nft or a marker. The README's image tracking example is the shortest complete version, and it must be served over a server rather than opened as a local file.
What is AR.js?
It is an MIT-licensed JavaScript library for augmented reality on the web, providing image tracking, location based AR and marker tracking. It ships separate builds for A-Frame and three.js, and the README states the builds are exclusive, so you import the one your project needs.
AR.js vs MindAR: which should I pick?
The AR.js README points readers who need strong image tracking, multiple image tracking or face tracking toward MindAR, and notes that AR.js remains the option for marker based and location based AR. So the split is by tracking mode rather than by overall quality.
What is the difference between AR.js and A-Frame?
They are not competing choices. A-Frame is the scene framework, and AR.js supplies the tracking and camera layer on top of it. The repository declares aframe as a dependency and ships aframe-ar.js and aframe-ar-nft.js as builds for that combination.
Does AR.js work with three.js instead of A-Frame?
Yes. The repository has a three.js directory with its own builds: ar-threex.js for image and marker tracking, ar.js for the ARjs namespace, and ar-threex-location-only.js for location only. three is listed as a dependency in package.json.
What can I use instead of AR.js?
The README itself recommends MindAR for image tracking, including multiple images, and for face tracking. For marker based and location based AR the README states AR.js is still the only library providing those features, so the alternative depends on which tracking mode you need.
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/ar-js-org-ar-js)