Library / SDK
arangodb/arangojs avatar
arangodb/arangojs

arangojs: the TypeScript client for driving ArangoDB from Node.js

The official ArangoDB JavaScript driver.

608 stars111 forksTypeScriptApache-2.0

At a glance

What is it?
arangojs is the official ArangoDB JavaScript driver, published as a dual ES module and CommonJS package with TypeScript types, an AQL template tag, and a browser build. It talks to a server from outside the database, which is exactly where it stops working.
Who is it for?
Adopt arangojs when your Node.js service or browser app needs to query an ArangoDB server from the outside and you want typed errors, an AQL template tag and a dual module build; skip it when the code runs inside the database, since Foxx and the arangosh shell have their own APIs.
Can I use it commercially?
Yes. Apache-2.0 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 8 days 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 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

arangojs is the outside-the-database client, and only that

The arangojs repository is the official ArangoDB JavaScript driver, and the README is unusually explicit about its scope. It is intended to be used in Node.js or a browser to access ArangoDB from outside the database. If you are looking for the ArangoDB JavaScript API for Foxx, or for reaching ArangoDB from within the arangosh interactive shell, the README points you elsewhere: to the documentation of the `@arangodb` module and to the `db` object. That boundary is worth understanding before you install anything, because the two environments look similar in code samples and fail differently. In arangojs a `Database` instance is a client that holds a URL, a database name and credentials, and every operation is a request to a server over the network. Inside the database there is no network hop and no client at all, since the code already runs next to the data. The primary language of the repository is TypeScript, and the published package carries type declarations, which matters for teams that want the compiler to catch a mistyped collection name.

The aql tag builds the query and the cursor streams the rows

The core usage pattern has two halves: a query built with the `aql` template tag, and a cursor that you consume asynchronously. The README gives this example for a modern TypeScript setup using async/await and ES modules.

js
import { Database, aql } from "arangojs";

const db = new Database();
const Pokemons = db.collection("my-pokemons");

async function main() {
  try {
    const pokemons = await db.query(aql`
      FOR pokemon IN ${Pokemons}
      FILTER pokemon.type == "fire"
      RETURN pokemon
    `);
    console.log("My pokemans, let me show you them:");
    for await (const pokemon of pokemons) {
      console.log(pokemon.name);
    }
  } catch (err) {
    console.error(err.message);
  }
}

main();

Two details carry most of the weight. The `aql` tag is a template literal helper, so a query can be written as AQL with interpolations rather than as a concatenated string, and a collection handle such as `Pokemons` can be embedded directly. The result of `db.query` is a cursor, and `for await` walks it, which means rows arrive lazily rather than as one array in memory. That is the difference between a driver that can page through a large result set and one that cannot.

One package for Node.js, CommonJS consumers and browsers

Installation for server-side use is a single package manager command, and the README offers both npm and yarn.

sh
npm install --save arangojs
## - or -
yarn add arangojs

The package manifest is what makes the same install work in very different codebases. The package is marked as an ES module, declares a Node.js engine requirement of 20 or newer, and exports separate entry points for import and require, so a modern bundler and a legacy CommonJS service can both consume it. The manifest also exposes subpath exports, including one for the lib directory, which lets application code reach individual helpers rather than only the package root. For browser use without a bundler, the README shows an import map pointing at the jsDelivr CDN.

html
<script type="importmap">
  {
    "imports": {
      "arangojs": "https://cdn.jsdelivr.net/npm/[email protected]/esm/index.js?+esm"
    }
  }
</script>
<script type="module">
  import { Database } from "arangojs";
  const db = new Database();
  // ...
</script>

Note the pinned version in that CDN URL. The driver does not track the browser build for you, so the version in the import map is yours to maintain.

Connecting to a named database and swapping credentials at runtime

The default constructor with no arguments targets the local server, which is what the examples assume. A real deployment passes a configuration object with a URL, a database name and credentials, as in the README's second example.

js
const db = new Database({
  url: "http://127.0.0.1:8529",
  databaseName: "pancakes",
  auth: { username: "root", password: "hunter2" },
});

// The credentials can be swapped at any time
db.useBasicAuth("admin", "maplesyrup");

The URL in that snippet is the default ArangoDB port, 8529, and it is plain HTTP rather than TLS, which is the right choice for a local server and the wrong choice anywhere else. The `useBasicAuth` call matters for long-running processes: a driver instance can be re-authenticated after the initial connection, which is how you rotate credentials without rebuilding the client. The credentials in the example are placeholders in the documentation, and the same caution applies to anything you copy from it. An older style of call is still supported for CommonJS codebases.

js
var arangojs = require("arangojs");
var Database = arangojs.Database;

var db = new Database();
var pokemons = db.collection("pokemons");

db.query({
  query: "FOR p IN @@c FILTER p.type == 'fire' RETURN p",
  bindVars: { "@c": "pokemons" },
})
  .then(function (cursor) {
    console.log("My pokemons, let me show you them:");
    return cursor.forEach(function (pokemon) {
      console.log(pokemon.name);
    });
  })
  .catch(function (err) {
    console.error(err.message);
  });

That last form uses the older query object with a `query` string and a `bindVars` map, and it consumes the cursor with a callback. The README explains that the modern examples rely on async/await, multi-line strings and template tags, and that environments without those features should substitute promises for await syntax as shown here.

Server errors and transport errors arrive as different classes

The driver separates failures into a small set of classes, and the distinction is worth designing your error handling around. When the server returns an ArangoDB error response, arangojs throws an `ArangoError` carrying an `errorNum` property with the ArangoDB error code, and the response body is exposed as the `response` property. For other failures during the request and response cycle, the driver throws a `NetworkError` or a more specific subclass, with the originating request available as the `request` property. When the server answered with a non-2xx status code, that `NetworkError` is an `HttpError` with a `code` property for the HTTP status and a `response` property for the response object. If the failure was caused by an exception, the original exception is available as the `cause` property, and for network errors this is often a `TypeError`. In Node.js specifically, those network errors frequently carry a `cause` holding the more detailed exception, sometimes a system error with its own `code` and `syscall` properties such as `connect`, and sometimes an error from the `undici` module that Node uses internally for its native `fetch` implementation. In other words, a failure that started as a timeout can be traced from the driver down to the system call, provided your code walks the `cause` chain rather than printing `err.message` and stopping.

Version 10 changed the API and the support window is narrow

The compatibility statement in the README is short and has teeth. The driver is compatible with the latest stable version of ArangoDB available at the time of the driver release, and it remains compatible with the two most recent Node.js LTS versions in line with the Node.js long-term support schedule. Versions of ArangoDB that have reached end of life by the time of a driver release are explicitly not supported. The package manifest tightens the Node.js side further with an engines requirement of 20 or newer, and the repository tracks the same line: the latest push was on 2026-10-15, and the releases listed are v10.6.0 on 2026-10-14, v10.5.0 on 2026-09-11 and v10.4.0 on 2026-08-18. The upgrade hazard is the major version. The README warns that a change in the major version number of arangojs, such as 9.x.y to 10.0.0, indicates backwards-incompatible changes in the API that may require changes in your code, and it points to a migration guide alongside the changelog. If your code was written against an older major version, pinning is the documented escape hatch.

sh
# for version 9.x.x
yarn add arangojs@9
# - or -
npm install --save arangojs@9

A note on browser support applies here too: the README advises confirming that your Node.js or browser version and your ArangoDB version are supported by the driver version you are trying to use, and that the documentation you are reading matches the driver version you installed.

Calling the REST API yourself instead of using the driver

The obvious alternative is to skip the driver and speak HTTP to the ArangoDB REST API with the native `fetch` that Node provides, or with an HTTP client of your choosing. The difference in approach is not about speed, it is about what each choice asks you to own. A hand-written client is a handful of lines per endpoint and gives you total control over headers, retries and timeouts, and it works against any server that speaks the API, including a version older than the driver supports. What you take on is authentication handling, error mapping, cursor pagination and the type layer. The driver turns a server error into an `ArangoError` with an `errorNum`, turns a non-2xx response into an `HttpError` with a status `code`, exposes the original exception as `cause`, and hands back a cursor that pages through results. Rebuilding those four behaviours is not free, and it is exactly the code that is easy to get subtly wrong and hard to notice until something breaks in production. If you only need to run a fixed read query occasionally, the REST route is defensible. If the client is shared by several services, the driver is usually the cheaper place to keep the protocol knowledge.

Apache-2.0 licensing, typed builds and a maintained release line

The driver is published under the Apache-2.0 licence, which the README badge and the package manifest both state. That licence is permissive, so it carries no copyleft requirement to release your own service source when you depend on it, though it does require preserving its licence and copyright notices in redistributed copies. The repository is not archived, and the last push was on 2026-10-15, one day after the v10.6.0 release, so the release line and the source tree move together. Building is a normal TypeScript toolchain setup: the repository holds a main tsconfig plus separate configurations for the CommonJS build and the declaration output, a typedoc configuration for the API documentation, and CircleCI configuration alongside the GitHub workflows. The test scripts run mocha over both build outputs, and a browser test script exercises the browser bundle, with a build step running before the tests. The documentation itself is hosted separately from the code, with an API reference, a changelog and a migration guide, all linked from the README. The practical upgrade path is therefore clear: read the migration guide before crossing a major version, and check the changelog for the release you are pinning.

Editorial conclusion

Adopt arangojs when your Node.js service or browser app needs to query an ArangoDB server from the outside and you want typed errors, an AQL template tag and a dual module build; skip it when the code runs inside the database, since Foxx and the arangosh shell have their own APIs. Verify first that your Node.js version is 20 or newer, that your ArangoDB server is the latest stable release, and that the driver major version has not changed under code you copied from an older example.

Frequently asked questions

How do I install arangojs for a Node.js project?

The README gives npm install --save arangojs, or yarn add arangojs as an alternative. The package manifest requires Node.js 20 or newer and ships both an ES module and a CommonJS entry point.

Can I use arangojs inside a Foxx service or in the arangosh shell?

No. The README states that arangojs is only intended for accessing ArangoDB from outside the database. Inside the database, the @arangodb module and the db object are the documented APIs.

How do I tell an ArangoDB server error apart from a network failure in arangojs?

A server error response throws an ArangoError with an errorNum property and the body on response, while request and response cycle failures throw a NetworkError or a subclass. A non-2xx status produces an HttpError with a code property.

Official sources

  1. arangodb/arangojs on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/arangodb-arangojs.svg)](https://hysenlabs.com/projects/arangodb-arangojs)