diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..d2490da83
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,32 @@
+Makefile
+CmakeLists.txt
+*yml
+build
+cmake
+misc
+.*
+*tgz
+benchmark
+expression-test
+cloudformation
+bin
+vendor
+include
+mason_packages
+mapbox-gl-js
+test
+lib
+next
+src
+scripts
+render-test
+platform/android
+platform/darwin
+platform/default
+platform/glfw
+platform/ios
+platform/linux
+platform/macos
+platform/qt
+platform/node/symbol-list
+platform/node/version-script
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 1c1199932..d80b71c79 100644
--- a/Makefile
+++ b/Makefile
@@ -149,6 +149,19 @@ offline: $(MACOS_PROJ_PATH)
 node: $(MACOS_PROJ_PATH)
 	set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-node (Active ABI)' build $(XCPRETTY)
 
+UNIX_BUILD = $(MACOS_OUTPUT_PATH)/build.ninja
+$(UNIX_BUILD): $(BUILD_DEPS)
+	mkdir -p $(MACOS_OUTPUT_PATH)
+	(cd $(MACOS_OUTPUT_PATH) && $(CMAKE) -G Ninja ../../ \
+		-DCMAKE_BUILD_TYPE=$(BUILDTYPE) \
+		-DWITH_COVERAGE=${WITH_COVERAGE} \
+		-DWITH_OSMESA=${WITH_OSMESA} \
+		-DWITH_EGL=${WITH_EGL})
+
+.PHONY: unode
+unode: $(UNIX_BUILD)
+	$(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(MACOS_OUTPUT_PATH) mbgl-node.active
+
 .PHONY: node-all
 node-all: $(MACOS_PROJ_PATH)
 	set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-node (All ABIs)' build $(XCPRETTY)
diff --git a/cmake/node.cmake b/cmake/node.cmake
index a791d99b4..edea4df71 100644
--- a/cmake/node.cmake
+++ b/cmake/node.cmake
@@ -20,8 +20,8 @@ create_source_groups(mbgl-loop-node)
 
 add_node_module(mbgl-node
     INSTALL_PATH "lib/{node_abi}/mbgl.node"
-    NAN_VERSION "2.10.0"
-    
+    NAN_VERSION "2.14.0"
+
     # Don't build for Node 4.x, 5.x, 7.x, 9.x, 11.x and 12.x
     # See https://nodejs.org/en/download/releases/ for mapping of Node version to ABI number.
     # Changes to this property should happen in tandem with updates to the version targets
diff --git a/package.json b/package.json
index 9b11a039c..90ec89de7 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
     "node": ">=6"
   },
   "scripts": {
-    "install": "node-pre-gyp install --fallback-to-build=false || make node",
+    "install": "node-pre-gyp install --fallback-to-build=false",
     "test": "tape platform/node/test/js/**/*.test.js",
     "test-memory": "node --expose-gc platform/node/test/memory.test.js",
     "test-expressions": "node -r esm platform/node/test/expression.test.js",
--- a/platform/node/DEVELOPING.md
+++ b/platform/node/DEVELOPING.md
@@ -8,25 +8,31 @@ To develop these bindings, you’ll need to build them from source. Building req
 the [macOS](../macos/INSTALL.md#requirements) or [Linux](../linux/README.md#prerequisites) install documentation, depending
 on the target platform.
 
-To compile the Node.js bindings and install module dependencies, from the repository root directory, run:
+To compile the Node.js bindings and install module dependencies, from the repository root directory, first run:
 
-    npm install --build-from-source
+```
+make distclean
+```
+
+If you are rebuilding after time has passed.
 
-To recompile just the C++ code while developing, run `make node`.
+Then do:
 
-To create an Xcode project and use a GUI debugger in the case of a crash, run `make xnode`.
+```bash
+make node
+```
 
 ## Testing
 
 To test the Node.js bindings:
 
-```
-npm test
+```bash
+make test-node
 ```
 
 To run the visual render test suite:
 
-```
+```bash
 npm run test-suite
 ```
 
diff --git a/platform/node/README.md b/platform/node/README.md
index 7273c0813..859172108 100644
--- a/platform/node/README.md
+++ b/platform/node/README.md
@@ -9,7 +9,7 @@ Requires a modern C++ runtime that supports C++14.
 By default, installs binaries. On these platforms no additional dependencies are needed.
 
 - 64 bit macOS or 64 bit Linux
-- Node.js v4.x _(note: v5+ is known to have issues)_
+- Node.js v10.x
 
 Run:
 
@@ -168,9 +168,9 @@ var map = new mbgl.Map({
                 if (res.headers.modified) { response.modified = new Date(res.headers.modified); }
                 if (res.headers.expires) { response.expires = new Date(res.headers.expires); }
                 if (res.headers.etag) { response.etag = res.headers.etag; }
-                
+
                 response.data = body;
-                
+
                 callback(null, response);
             } else {
                 callback(new Error(JSON.parse(body).message));
