diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 06509ca99eb8f66575ac76b386844be0cde5ba5f..02ff369a400773bb46529f28def0bf579167aba9 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -780,6 +780,13 @@ const options = [
     default: { enabled: false },
     mergeable: true,
   },
+  {
+    name: 'nvm',
+    description: 'Configuration object for .nvmrc files',
+    state: 'repository',
+    type: 'json',
+    default: { enabled: true },
+  },
   {
     name: 'docker',
     description: 'Configuration object for Dockerfile renovation',
diff --git a/lib/manager/index.js b/lib/manager/index.js
index 9ec78db90be80e7dd1efbce131d357f036c5e28a..c1c1a6ef115267ea0623087f9169c5a1812aa8ab 100644
--- a/lib/manager/index.js
+++ b/lib/manager/index.js
@@ -3,7 +3,7 @@ const { mergeChildConfig } = require('../config');
 const { checkMonorepos } = require('../manager/npm/monorepos');
 
 const managers = {};
-const managerList = ['bazel', 'docker', 'meteor', 'npm', 'travis'];
+const managerList = ['bazel', 'docker', 'meteor', 'npm', 'nvm', 'travis'];
 for (const manager of managerList) {
   // eslint-disable-next-line global-require,import/no-dynamic-require
   managers[manager] = require(`./${manager}`);
@@ -112,6 +112,7 @@ async function resolvePackageFiles(config) {
       : await detectPackageFiles(config);
   logger.debug({ allPackageFiles }, 'allPackageFiles');
   const managerFileMappings = {
+    '.nvmrc': 'nvm',
     '.travis.yml': 'travis',
     Dockerfile: 'docker',
     WORKSPACE: 'bazel',
diff --git a/lib/manager/nvm/detect.js b/lib/manager/nvm/detect.js
new file mode 100644
index 0000000000000000000000000000000000000000..922bc40d1885abc5a6f9a2beb04e356c82c7f577
--- /dev/null
+++ b/lib/manager/nvm/detect.js
@@ -0,0 +1,13 @@
+module.exports = {
+  detectPackageFiles,
+};
+
+function detectPackageFiles(config, fileList) {
+  logger.debug('nvm.detectPackageFiles()');
+  if (config.nvm.enabled) {
+    if (fileList.includes('.nvmrc')) {
+      return ['.nvmrc'];
+    }
+  }
+  return [];
+}
diff --git a/lib/manager/nvm/extract.js b/lib/manager/nvm/extract.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d2111943345bc66b17527b0cc451a9146a30bb2
--- /dev/null
+++ b/lib/manager/nvm/extract.js
@@ -0,0 +1,13 @@
+module.exports = {
+  extractDependencies,
+};
+
+function extractDependencies(packageContent) {
+  return [
+    {
+      depName: 'node',
+      depType: '.nvmrc',
+      currentVersion: packageContent.trim(),
+    },
+  ];
+}
diff --git a/lib/manager/nvm/index.js b/lib/manager/nvm/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..6b0c9b22a06d47a8c79c7a0517cb7f30bafde0cd
--- /dev/null
+++ b/lib/manager/nvm/index.js
@@ -0,0 +1,13 @@
+const { detectPackageFiles } = require('./detect');
+const { extractDependencies } = require('./extract');
+const { getPackageUpdates } = require('./package');
+const { resolvePackageFile } = require('./resolve');
+const { setNewValue } = require('./update');
+
+module.exports = {
+  detectPackageFiles,
+  extractDependencies,
+  getPackageUpdates,
+  resolvePackageFile,
+  setNewValue,
+};
diff --git a/lib/manager/nvm/package.js b/lib/manager/nvm/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..75a8b35efd88c4ffd15798cc5c3cef244da476c3
--- /dev/null
+++ b/lib/manager/nvm/package.js
@@ -0,0 +1,10 @@
+const nodeManager = require('../_helpers/node/package');
+
+module.exports = {
+  getPackageUpdates,
+};
+
+function getPackageUpdates(config) {
+  logger.debug('nvm.getPackageUpdates()');
+  return nodeManager.getPackageUpdates(config);
+}
diff --git a/lib/manager/nvm/resolve.js b/lib/manager/nvm/resolve.js
new file mode 100644
index 0000000000000000000000000000000000000000..f39498a03f6d7dc4a66cac37978bc33dd77050a3
--- /dev/null
+++ b/lib/manager/nvm/resolve.js
@@ -0,0 +1,19 @@
+const { mergeChildConfig } = require('../../config');
+
+module.exports = {
+  resolvePackageFile,
+};
+
+async function resolvePackageFile(config, inputFile) {
+  const nvmConfig = mergeChildConfig(config.node, config.nvm);
+  const packageFile = mergeChildConfig(nvmConfig, inputFile);
+  logger.debug(
+    `Resolving packageFile ${JSON.stringify(packageFile.packageFile)}`
+  );
+  packageFile.content = await platform.getFile(packageFile.packageFile);
+  if (!packageFile.content) {
+    logger.debug('No packageFile content');
+    return null;
+  }
+  return packageFile;
+}
diff --git a/lib/manager/nvm/update.js b/lib/manager/nvm/update.js
new file mode 100644
index 0000000000000000000000000000000000000000..3d371c5a8ca319c413361e82a560731c9b73b616
--- /dev/null
+++ b/lib/manager/nvm/update.js
@@ -0,0 +1,8 @@
+module.exports = {
+  setNewValue,
+};
+
+function setNewValue(currentFileContent, upgrade) {
+  logger.debug(`nvm.setNewValue: ${upgrade.newVersions}`);
+  return `${upgrade.newVersion}\n`;
+}
diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.js
index c5b945846a799d61c5b718328b94f4e11f6b1fd6..88d8a12b477d34070703808a74fc2e8b51e8a75b 100644
--- a/lib/workers/pr/index.js
+++ b/lib/workers/pr/index.js
@@ -111,7 +111,11 @@ async function ensurePr(prConfig) {
     processedUpgrades.push(upgradeKey);
 
     let logJSON;
-    if (upgrade.depType !== 'engines') {
+    if (
+      upgrade.manager !== 'travis' &&
+      upgrade.manager !== 'nvm' &&
+      upgrade.depType !== 'engines'
+    ) {
       logJSON = await changelogHelper.getChangeLogJSON(
         upgrade.depName,
         upgrade.changeLogFromVersion,
diff --git a/test/manager/__snapshots__/index.spec.js.snap b/test/manager/__snapshots__/index.spec.js.snap
index cf561e12e6197a3c13093efd72b0dbd5f8d42f08..91c455b74987ecbea361deba72e76d2c7f69b849 100644
--- a/test/manager/__snapshots__/index.spec.js.snap
+++ b/test/manager/__snapshots__/index.spec.js.snap
@@ -7,6 +7,12 @@ Array [
 ]
 `;
 
+exports[`manager detectPackageFiles(config) finds .nvmrc files 1`] = `
+Array [
+  ".nvmrc",
+]
+`;
+
 exports[`manager detectPackageFiles(config) finds .travis.yml files 1`] = `
 Array [
   ".travis.yml",
diff --git a/test/manager/__snapshots__/resolve.spec.js.snap b/test/manager/__snapshots__/resolve.spec.js.snap
index 6f661ff19a652d8bd900fcf2023bbdbcc2bd9449..643d46f1b717183c71939924e5c798f6ae08a26c 100644
--- a/test/manager/__snapshots__/resolve.spec.js.snap
+++ b/test/manager/__snapshots__/resolve.spec.js.snap
@@ -42,7 +42,7 @@ Array [
 ]
 `;
 
-exports[`manager/resolve resolvePackageFiles() detects meteor and docker and travis and bazel 1`] = `
+exports[`manager/resolve resolvePackageFiles() detects meteor and docker and travis and bazel and nvm 1`] = `
 Array [
   Object {
     "content": "{}",
@@ -270,8 +270,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
     "prTitle": "Update {{{depName}}} Dockerfile tag to {{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newTag}}}{{/if}}",
   },
   Object {
-    "content": "hello: world
-",
+    "content": "# travis",
     "enabled": false,
     "groupName": "node.js",
     "lazyGrouping": false,
@@ -279,11 +278,20 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
     "packageFile": ".travis.yml",
   },
   Object {
-    "content": "# travis",
+    "content": "# WORKSPACE",
     "enabled": true,
     "manager": "bazel",
     "packageFile": "WORKSPACE",
   },
+  Object {
+    "content": "8.9
+",
+    "enabled": true,
+    "groupName": "node.js",
+    "lazyGrouping": false,
+    "manager": "nvm",
+    "packageFile": ".nvmrc",
+  },
 ]
 `;
 
diff --git a/test/manager/index.spec.js b/test/manager/index.spec.js
index e6f5687d20a2ff2dc559070bb488af0e113d5291..cc56dc3f959de5d3f60ec0c0f057ae6531d2178e 100644
--- a/test/manager/index.spec.js
+++ b/test/manager/index.spec.js
@@ -78,6 +78,13 @@ describe('manager', () => {
       expect(res).toMatchSnapshot();
       expect(res).toHaveLength(1);
     });
+    it('finds .nvmrc files', async () => {
+      config.travis.enabled = true;
+      platform.getFileList.mockReturnValueOnce(['.nvmrc', 'other/.nvmrc']);
+      const res = await manager.detectPackageFiles(config);
+      expect(res).toMatchSnapshot();
+      expect(res).toHaveLength(1);
+    });
     it('finds WORKSPACE files', async () => {
       config.bazel.enabled = true;
       platform.getFileList.mockReturnValueOnce([
diff --git a/test/manager/nvm/__snapshots__/extract.spec.js.snap b/test/manager/nvm/__snapshots__/extract.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..1b783d2a472554b8ecbe40794794c87bc50aca59
--- /dev/null
+++ b/test/manager/nvm/__snapshots__/extract.spec.js.snap
@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`lib/manager/nvm/extract extractDependencies() returns a result 1`] = `
+Array [
+  Object {
+    "currentVersion": "8.4.0",
+    "depName": "node",
+    "depType": ".nvmrc",
+  },
+]
+`;
diff --git a/test/manager/nvm/__snapshots__/package.spec.js.snap b/test/manager/nvm/__snapshots__/package.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..acf0751f45a19504773edababc727b79911b109c
--- /dev/null
+++ b/test/manager/nvm/__snapshots__/package.spec.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`lib/workers/package/node getPackageUpdates returns result if needing updates 1`] = `Array []`;
diff --git a/test/manager/nvm/__snapshots__/update.spec.js.snap b/test/manager/nvm/__snapshots__/update.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..e938db537a6e2efde93d1459c9eeba39f1df6e80
--- /dev/null
+++ b/test/manager/nvm/__snapshots__/update.spec.js.snap
@@ -0,0 +1,6 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/nvm/update setNewValue updates values 1`] = `
+"8.9.1
+"
+`;
diff --git a/test/manager/nvm/extract.spec.js b/test/manager/nvm/extract.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d13e4d2d45346fe88ee23e36090b0a7cd2187458
--- /dev/null
+++ b/test/manager/nvm/extract.spec.js
@@ -0,0 +1,10 @@
+const { extractDependencies } = require('../../../lib/manager/nvm/extract');
+
+describe('lib/manager/nvm/extract', () => {
+  describe('extractDependencies()', () => {
+    it('returns a result', () => {
+      const res = extractDependencies('8.4.0\n');
+      expect(res).toMatchSnapshot();
+    });
+  });
+});
diff --git a/test/manager/nvm/package.spec.js b/test/manager/nvm/package.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c53f378b2474e072f6d1e4231d8fbcd505a1370
--- /dev/null
+++ b/test/manager/nvm/package.spec.js
@@ -0,0 +1,22 @@
+const node = require('../../../lib/manager/nvm/package');
+const defaultConfig = require('../../../lib/config/defaults').getConfig();
+
+describe('lib/workers/package/node', () => {
+  describe('getPackageUpdates', () => {
+    let config;
+    beforeEach(() => {
+      config = {
+        ...defaultConfig,
+      };
+    });
+    it('returns empty if matching', async () => {
+      config.currentVersion = ['6', '8'];
+      config.supportPolicy = ['lts_active'];
+      expect(await node.getPackageUpdates(config)).toEqual([]);
+    });
+    it('returns result if needing updates', async () => {
+      config.currentVersion = ['6', '8'];
+      expect(await node.getPackageUpdates(config)).toMatchSnapshot();
+    });
+  });
+});
diff --git a/test/manager/nvm/update.spec.js b/test/manager/nvm/update.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..529499f6007895949c9188f5277ed7e782f07bcc
--- /dev/null
+++ b/test/manager/nvm/update.spec.js
@@ -0,0 +1,13 @@
+const nodefile = require('../../../lib/manager/nvm/update');
+
+describe('manager/nvm/update', () => {
+  describe('setNewValue', () => {
+    it('updates values', () => {
+      const upgrade = {
+        newVersion: '8.9.1',
+      };
+      const res = nodefile.setNewValue('8.9.0\n', upgrade);
+      expect(res).toMatchSnapshot();
+    });
+  });
+});
diff --git a/test/manager/resolve.spec.js b/test/manager/resolve.spec.js
index c30ff35c6d4f2d9d752d041a78026c2679d9cd1a..78c9d002b421cbf5d42ed0a6d77b1114bf257bbe 100644
--- a/test/manager/resolve.spec.js
+++ b/test/manager/resolve.spec.js
@@ -94,18 +94,19 @@ describe('manager/resolve', () => {
       expect(res.packageFiles).toMatchSnapshot();
       expect(res.warnings).toHaveLength(0);
     });
-    it('detects meteor and docker and travis and bazel', async () => {
+    it('detects meteor and docker and travis and bazel and nvm', async () => {
       config.packageFiles = [
         'package.js',
         'Dockerfile',
         '.travis.yml',
         'WORKSPACE',
+        '.nvmrc',
       ];
       platform.getFile.mockReturnValueOnce('{}'); // package.js
       platform.getFile.mockReturnValueOnce('# comment\nFROM node:8\n'); // Dockerfile
-      platform.getFile.mockReturnValueOnce('hello: world\n'); // Dockerfile
       platform.getFile.mockReturnValueOnce('# travis'); // .travis.yml
       platform.getFile.mockReturnValueOnce('# WORKSPACE'); // Dockerfile
+      platform.getFile.mockReturnValueOnce('8.9\n'); // Dockerfile
       const res = await resolvePackageFiles(config);
       expect(res.packageFiles).toMatchSnapshot();
     });
@@ -116,6 +117,7 @@ describe('manager/resolve', () => {
         '.travis.yml',
         'WORKSPACE',
         'package.js',
+        '.nvmrc',
       ];
       platform.getFile.mockReturnValueOnce('# comment\n'); // Dockerfile
       const res = await resolvePackageFiles(config);
diff --git a/website/docs/_posts/2017-10-05-configuration-options.md b/website/docs/_posts/2017-10-05-configuration-options.md
index 991e8b6b65aa5b4774aaa04fae92d560a73b28a5..f41a95b7d221f3782772ba7c2b7b146539e27403 100644
--- a/website/docs/_posts/2017-10-05-configuration-options.md
+++ b/website/docs/_posts/2017-10-05-configuration-options.md
@@ -551,6 +551,17 @@ A string copy of npmrc file.
 
 See https://renovateapp.com/docs/deep-dives/private-modules for details on how this is used.
 
+## nvm
+
+Configuration specific for `.nvmrc` files.
+
+| name    | value             |
+| ------- | ----------------- |
+| type    | object            |
+| default | { enabled: true } |
+
+For settings common to all node.js version updates (e.g. travis, nvm, etc) you can use the `node` object instead.
+
 ## optionalDependencies
 
 Configuration specific for `package.json > optionalDependencies`.