Skip To Content
Back to Blog

A Node.js ArcGIS Client Library

by Nikolas Wise

What's this about?

This project is a bare-bones library to ease interactions with the ArcGIS REST API in JavaScript and Node apps. Right now, the library wraps most of the basic platform content management and interactions - getting and editing users, organizations, and items. The Node ArcGIS Client Library is an open source project — so it's scope will increase as the community works to accomplish more goals and workflows.

This project works to simplify and unify the gap between the ArcGIS REST API and a contemporary Node application. This library is a UI in the most basic sense of the term — it provides an interface between the developer and the servers. That interface needs to be well designed and thoughtful in order to make the process as smooth, intuitive, and pleasurable as possible.

One of the most important parts of the project is to provide developers with a way to access the ArcGIS platform without needing to architect their entire application around opinionated frameworks (like Dojo, for example). Though the library itself is written in ES6, it's distributed as plain, normal ES5 – both as a node package and a packaged bundle. This means it works both in Node and the browser, and has very few opinions on how it integrates with the rest of your app.

Setting up the client

The first step in using the library is initializing the client with your target portal.

var ArcGIS = require('arcgis')
var arcgis = ArcGIS()

This sets up a default object for interacting with the API. This default is going to talk to ArcGIS Online as an anonymous, unauthenticated user. One can authenticate this client session as a named user by passing in a user token obtained from a successful OAuth login process.

var arcgis = Arcgis({
  token: namedUserToken

This isn't exclusive to ArcGIS Online. The API for interacting with your organization's installation of Portal or Server is the same. Setting up the client session with your instance is done by specifying your API domain.

var arcgis = Arcgis({
  domain: '',
  token: namedUserToken

Beyond the initialization of the client, the library is exclusively async. All the functions return promises by default.

function log (m) {
function ohNo (err) {
  return new Error(err)

You can also pass in a node-style callback, if you'd prefer.

function log (err, results) {
  if (err) {
    return new Error(err)
  } else {
arcgis.request({}, log)

Both methods work just as well, and use all the same business logic. I like promises, but maybe you don't. This is one of the main reasons the library does its best to avoid inflicting my opinions on your codebase.

Once we have an authenticated session, we can do all sorts of stuff — like figure out who we are:

function hello (user) {
  console.log('Hello, ' + user.firstName)

We can get all of the items that user has in the platform:

function getContent (user) {
  return user.content()
function logContent (content) {

Or a list of all the groups that a user is a member of.

function logGroups (item) {
  item.groups.forEach(function (group) {

The library also can interact with the user's organization, returning information, members, or all the content associated with the organization.

function logOrg (org) {

The organization call defaults to 'self' — whatever organization the current user is a member of.

function getMembers (org) {
  return org.members()
function log (members) {

Many of the content calls are abstractions or helper methods for longer, more complicated calls to the search endpoint.

function getContent (org) {
  return org.content()
function log (items) {

In this way we are able to create a transitional layer between the API itself (a super complicated call to the search endpoint) and what application developers need (all my organization's content).

Working with content

Platform content is the weakest link in the library as of today. ArcGIS supports a huge range of item types, and quite a number of sophisticated things you can do with those item types. For now the basics are more or less in place — like getting an item's details:

var layerID = 'a5e5e5ac3cfc44dfa8e90b92cd7289fb'
function logItem (item) {

Or updating the those details and editing the permissions:

var layerId = 'a5e5e5ac3cfc44dfa8e90b92cd7289fb'
function updateItem (item) {
  return item.update({
    snippet: 'Building footprints in my neighborhood in Portland, Oregon'
function shareItem (item) {
  return item.permissions({
    access: 'public'

So far, there's some support for item-type-specific methods that are starting to open up the possibilities of manipulating your content from Node — like getting all the data in a layer.

var layerID = 'a5e5e5ac3cfc44dfa8e90b92cd7289fb'
function getData (item) {
function logData (data) {

Where we're going from here

There is a lot more of the platform that we could cover than this - services, analysis, layer creation and tile publishing all are actions that this library or ones like it could cover. To get there, and cover all our bases and weird edge cases, we're going to need help from the GIS community. That's why the project is open source on Github right now!

Report bugs, open issues, fork your own and open pull requests with the features you'd like most to see - or workflows you've navigated through in the REST API a dozen times already and wish were simpler.

And be sure to let us know if you use the library for interesting things! There are a couple of places where it's inching closer to production here at Esri, and we would absolutely love it if you beat us to it.