diff --git a/docs/configuration.md b/docs/configuration.md
index f39950b92b59b5d78fc8a312a9779da7a44f910d..7b128073bb2538fb81995308319b8c9b7753aec8 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -749,6 +749,28 @@ location with this method.
   <td>`RENOVATE_METEOR`</td>
   <td>`--meteor`<td>
 </tr>
+<tr>
+  <td>`supportPolicy`</td>
+  <td>Dependency support policy, e.g. used for LTS vs non-LTS etc (node-only)</td>
+  <td>list</td>
+  <td><pre>[]</pre></td>
+  <td>`RENOVATE_SUPPORT_POLICY`</td>
+  <td>`--support-policy`<td>
+</tr>
+<tr>
+  <td>`node`</td>
+  <td>Configuration object for node version renovation</td>
+  <td>json</td>
+  <td><pre>{
+  "enabled": false,
+  "supportPolicy": ["lts"],
+  "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+  "prBody": "This Pull Request updates `{{depName}}` versions from `{{currentVersions}}` to `{{newVersions}}`. This is according to the configured node.js support policy \"{{supportPolicy}}\".\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis PR has been generated by [Renovate Bot](https://renovateapp.com).",
+  "prTitle": "Update {{depName}} versions to [{{newVersions}}]"
+}</pre></td>
+  <td>`RENOVATE_NODE`</td>
+  <td>`--node`<td>
+</tr>
 <tr>
   <td>`docker`</td>
   <td>Configuration object for Dockerfile renovation</td>
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index b04802f417197b1265ed7cb8f42819d71b74b529..e6abf183620cbd5c014199cbd8b0fba66d08a79f 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -638,6 +638,27 @@ const options = [
     default: { enabled: true },
     mergeable: true,
   },
+  {
+    name: 'supportPolicy',
+    description:
+      'Dependency support policy, e.g. used for LTS vs non-LTS etc (node-only)',
+    type: 'list',
+    allowString: true,
+  },
+  {
+    name: 'node',
+    description: 'Configuration object for node version renovation',
+    stage: 'repository',
+    type: 'json',
+    default: {
+      enabled: false,
+      supportPolicy: ['lts'],
+      branchName: template('branchName', 'node'),
+      prBody: template('prBody', 'node'),
+      prTitle: template('prTitle', 'node'),
+    },
+    mergeable: true,
+  },
   {
     name: 'docker',
     description: 'Configuration object for Dockerfile renovation',
diff --git a/lib/config/templates/node/branch-name.hbs b/lib/config/templates/node/branch-name.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..38a6f040dfed949579273a93c2abba02546b27bf
--- /dev/null
+++ b/lib/config/templates/node/branch-name.hbs
@@ -0,0 +1 @@
+{{branchPrefix}}node-{{depNameSanitized}}
diff --git a/lib/config/templates/node/pr-body.hbs b/lib/config/templates/node/pr-body.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..d2686f92cfe91ac69626fe67c036cd7be96b5ca8
--- /dev/null
+++ b/lib/config/templates/node/pr-body.hbs
@@ -0,0 +1,35 @@
+This Pull Request updates `{{depName}}` versions from `{{currentVersions}}` to `{{newVersions}}`. This is according to the configured node.js support policy "{{supportPolicy}}".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule ("{{schedule}}"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   `{{error.depName}}`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   `{{warning.depName}}`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).
diff --git a/lib/config/templates/node/pr-title.hbs b/lib/config/templates/node/pr-title.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..55ab0e503e740fb77e79bc2553834560a23e7e59
--- /dev/null
+++ b/lib/config/templates/node/pr-title.hbs
@@ -0,0 +1 @@
+Update {{depName}} versions to [{{newVersions}}]
diff --git a/lib/manager/index.js b/lib/manager/index.js
index 8d75c48efab2c2cdf5872373f496c2e44218ebd9..7822746ec98b89e58dd7e625c9e3a1d24602a0d9 100644
--- a/lib/manager/index.js
+++ b/lib/manager/index.js
@@ -2,14 +2,17 @@ const minimatch = require('minimatch');
 
 const docker = require('./docker/package');
 const npm = require('./npm/package');
+const node = require('./node/package');
 
 const dockerDetect = require('./docker/detect');
 const meteorDetect = require('./meteor/detect');
 const npmDetect = require('./npm/detect');
+const nodeDetect = require('./node/detect');
 
 const npmUpdater = require('./npm/update');
 const meteorUpdater = require('./meteor/update');
 const dockerfileHelper = require('./docker/update');
+const nodeHelper = require('./node/update');
 
 module.exports = {
   detectPackageFiles,
@@ -42,6 +45,11 @@ async function detectPackageFiles(config) {
     logger.info({ dockerFiles }, 'Found Dockerfiles');
     packageFiles = packageFiles.concat(dockerFiles);
   }
+  const nodeFiles = await nodeDetect.detectPackageFiles(config, fileList);
+  if (nodeFiles.length) {
+    logger.info({ nodeFiles }, 'Found node files');
+    packageFiles = packageFiles.concat(nodeFiles);
+  }
   return packageFiles;
 }
 
@@ -52,6 +60,8 @@ function getPackageUpdates(config) {
     return npm.getPackageUpdates(config);
   } else if (config.packageFile.endsWith('package.js')) {
     return npm.getPackageUpdates(config);
+  } else if (config.packageFile.endsWith('.travis.yml')) {
+    return node.getPackageUpdates(config);
   }
   logger.info(`Cannot find manager for ${config.packageFile}`);
   throw new Error('Unsupported package manager');
@@ -82,6 +92,8 @@ async function getUpdatedPackageFiles(config) {
         );
       } else if (upgrade.packageFile.endsWith('Dockerfile')) {
         newContent = dockerfileHelper.setNewValue(existingContent, upgrade);
+      } else if (upgrade.packageFile.endsWith('.travis.yml')) {
+        newContent = nodeHelper.setNewValue(existingContent, upgrade);
       }
       if (!newContent) {
         if (config.parentBranch && config.canRebase) {
diff --git a/lib/manager/node/detect.js b/lib/manager/node/detect.js
new file mode 100644
index 0000000000000000000000000000000000000000..74901d29e3fa74e90fa6f76d29c4d2dcb386845a
--- /dev/null
+++ b/lib/manager/node/detect.js
@@ -0,0 +1,13 @@
+module.exports = {
+  detectPackageFiles,
+};
+
+function detectPackageFiles(config, fileList) {
+  logger.debug('node.detectPackageFiles()');
+  if (config.node.enabled) {
+    if (fileList.includes('.travis.yml')) {
+      return ['.travis.yml'];
+    }
+  }
+  return [];
+}
diff --git a/lib/manager/node/extract.js b/lib/manager/node/extract.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2c0ffbba752aed6dd43b12abf04637795cd5b83
--- /dev/null
+++ b/lib/manager/node/extract.js
@@ -0,0 +1,13 @@
+const yaml = require('js-yaml');
+
+module.exports = {
+  extractDependencies,
+};
+
+function extractDependencies(packageContent) {
+  const doc = yaml.safeLoad(packageContent);
+  if (doc && Array.isArray(doc.node_js)) {
+    return [{ depName: 'Travis node_js', currentVersions: doc.node_js }];
+  }
+  return [];
+}
diff --git a/lib/manager/node/package.js b/lib/manager/node/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..6757cbf7fc16745f6ba0d31faed4f4b4b5218429
--- /dev/null
+++ b/lib/manager/node/package.js
@@ -0,0 +1,36 @@
+const { isEqual } = require('lodash');
+
+module.exports = {
+  getPackageUpdates,
+};
+
+// Start version numbers as integers for correct sorting
+const policies = {
+  lts: [4, 6, 8],
+  active: [6, 8, 9],
+  current: [9],
+  lts_active: [6, 8],
+  lts_latest: [8],
+};
+
+function getPackageUpdates(config) {
+  logger.debug('node.getPackageUpdates()');
+  if (!Array.isArray(config.supportPolicy) || !config.supportPolicy.length) {
+    return [];
+  }
+  const newVersions = config.supportPolicy
+    .map(supportPolicy => policies[supportPolicy])
+    .reduce((result, supportPolicy) => result.concat(supportPolicy), [])
+    .sort() // sort combined array
+    .reverse() // we want to order latest to oldest
+    .map(version => `${version}`); // convert to strings
+  logger.debug({ newVersions });
+  if (isEqual([...config.currentVersions].sort(), [...newVersions].sort())) {
+    return [];
+  }
+  return [
+    {
+      newVersions,
+    },
+  ];
+}
diff --git a/lib/manager/node/resolve.js b/lib/manager/node/resolve.js
new file mode 100644
index 0000000000000000000000000000000000000000..67bf47230fe63f0000aa4d574e871dbf4a82577e
--- /dev/null
+++ b/lib/manager/node/resolve.js
@@ -0,0 +1,18 @@
+const configParser = require('../../config');
+
+module.exports = {
+  resolvePackageFile,
+};
+
+async function resolvePackageFile(config, inputFile) {
+  const packageFile = configParser.mergeChildConfig(config.node, 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/node/update.js b/lib/manager/node/update.js
new file mode 100644
index 0000000000000000000000000000000000000000..81401df2c91c1da23b8da7592afbcf0a2206f864
--- /dev/null
+++ b/lib/manager/node/update.js
@@ -0,0 +1,20 @@
+const detectIndent = require('detect-indent');
+
+module.exports = {
+  setNewValue,
+};
+
+function setNewValue(currentFileContent, upgrade) {
+  try {
+    logger.debug(`node.setNewValue: ${upgrade.newVersions}`);
+    const indent = detectIndent(currentFileContent).indent || '  ';
+    let newString = `\nnode_js:\n`;
+    upgrade.newVersions.forEach(version => {
+      newString += `${indent}- '${version}'\n`;
+    });
+    return currentFileContent.replace(/\nnode_js:(\n\s+[^\n]+)+\n/, newString);
+  } catch (err) {
+    logger.info({ err }, 'Error setting new .travis.yml node versions');
+    return null;
+  }
+}
diff --git a/lib/manager/resolve.js b/lib/manager/resolve.js
index c7f74a42c38b5aaa78bf692a3389a09ed56b74e0..4575dddabbda5cb23238af67d1cc471781ed20b5 100644
--- a/lib/manager/resolve.js
+++ b/lib/manager/resolve.js
@@ -6,6 +6,7 @@ const presets = require('../config/presets');
 
 const manager = require('./index');
 const dockerResolve = require('../manager/docker/resolve');
+const nodeResolve = require('../manager/node/resolve');
 const { mergeChildConfig } = require('../config');
 const { checkMonorepos } = require('../manager/npm/monorepos');
 
@@ -125,6 +126,9 @@ async function resolvePackageFiles(config) {
     } else if (packageFile.packageFile.endsWith('Dockerfile')) {
       logger.debug('Resolving Dockerfile');
       return dockerResolve.resolvePackageFile(config, packageFile);
+    } else if (packageFile.packageFile.endsWith('.travis.yml')) {
+      logger.debug('Resolving .travis.yml');
+      return nodeResolve.resolvePackageFile(config, packageFile);
     }
     return null;
   }
diff --git a/lib/workers/dep-type/index.js b/lib/workers/dep-type/index.js
index bfaab69d76b6cb59287aa825a2fe2dacd4ca5b44..89018691c789f012570269207aeb33cfd1ef7e3e 100644
--- a/lib/workers/dep-type/index.js
+++ b/lib/workers/dep-type/index.js
@@ -3,6 +3,7 @@ const pkgWorker = require('../package');
 const packageJson = require('./package-json');
 const dockerExtract = require('../../manager/docker/extract');
 const meteorExtract = require('../../manager/meteor/extract');
+const nodeExtract = require('../../manager/node/extract');
 
 module.exports = {
   renovateDepType,
@@ -38,6 +39,8 @@ async function renovateDepType(packageContent, config) {
     deps = meteorExtract.extractDependencies(packageContent);
   } else if (config.packageFile.endsWith('Dockerfile')) {
     deps = dockerExtract.extractDependencies(packageContent);
+  } else if (config.packageFile.endsWith('.travis.yml')) {
+    deps = nodeExtract.extractDependencies(packageContent);
   }
   deps = deps.filter(
     dependency => config.ignoreDeps.indexOf(dependency.depName) === -1
diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js
index 4762bd858d4a7232f03f77dc0737de560b542002..eceb3ad5789246c7f351e6e6cc1a5e4532562d51 100644
--- a/lib/workers/package-file/index.js
+++ b/lib/workers/package-file/index.js
@@ -7,6 +7,7 @@ module.exports = {
   renovatePackageFile,
   renovateMeteorPackageFile,
   renovateDockerfile,
+  renovateNodeFile,
 };
 
 function mightBeABrowserLibrary(packageJson) {
@@ -136,3 +137,22 @@ async function renovateDockerfile(packageFileConfig) {
   logger.info('Finished processing Dockerfile');
   return upgrades;
 }
+
+async function renovateNodeFile(packageFileConfig) {
+  let upgrades = [];
+  logger.info(`Processing node file`);
+
+  // Check if config is disabled
+  if (packageFileConfig.enabled === false) {
+    logger.info('node is disabled');
+    return upgrades;
+  }
+  upgrades = upgrades.concat(
+    await depTypeWorker.renovateDepType(
+      packageFileConfig.content,
+      packageFileConfig
+    )
+  );
+  logger.info('Finished processing node file');
+  return upgrades;
+}
diff --git a/lib/workers/repository/updates/determine.js b/lib/workers/repository/updates/determine.js
index 7c95eaa405693694e41e1e70a3c7d6e11c301913..ddd3d6e722885d009b0c10396a7bef9c58a5deb9 100644
--- a/lib/workers/repository/updates/determine.js
+++ b/lib/workers/repository/updates/determine.js
@@ -30,6 +30,11 @@ async function determineRepoUpgrades(config) {
       upgrades = upgrades.concat(
         await packageFileWorker.renovateDockerfile(packageFileConfig)
       );
+    } else if (packageFileConfig.packageFile.endsWith('.travis.yml')) {
+      logger.info('Renovating .travis.yml node_js versions');
+      upgrades = upgrades.concat(
+        await packageFileWorker.renovateNodeFile(packageFileConfig)
+      );
     }
   }
   let semanticCommits;
@@ -44,6 +49,7 @@ async function determineRepoUpgrades(config) {
       ? upgrade.depName
           .replace('@', '')
           .replace('/', '-')
+          .replace(/\s+/g, '-')
           .toLowerCase()
       : undefined,
   }));
diff --git a/package.json b/package.json
index dfc6e4f92f3c86314e0d478f26471df7df194071..6cb27f0616dc96ba4eb6ca18ea0a27c4b97d1c88 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
     "conventional-commits-detector": "0.1.1",
     "convert-hrtime": "2.0.0",
     "deepcopy": "0.6.3",
+    "detect-indent": "5.0.0",
     "fs-extra": "4.0.2",
     "get-installed-path": "4.0.8",
     "gh-got": "7.0.0",
@@ -57,6 +58,7 @@
     "got": "8.0.1",
     "handlebars": "4.0.11",
     "ini": "1.3.5",
+    "js-yaml": "3.10.0",
     "json-dup-key-validator": "1.0.2",
     "json-stringify-pretty-compact": "1.0.4",
     "jsonwebtoken": "8.1.0",
diff --git a/test/_fixtures/node/travis.yml b/test/_fixtures/node/travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7482c4c09aa6508483dc04c68d0b0926c0ce4bbb
--- /dev/null
+++ b/test/_fixtures/node/travis.yml
@@ -0,0 +1,21 @@
+dist: trusty
+language: node_js
+node_js:
+  - '8'
+  - '6'
+  - '4'
+services:
+  - redis-server
+  - mongodb
+  - mysql
+addons:
+  postgresql: '9.5'
+before_script:
+  - psql -c 'create database keyv_test;' -U postgres
+  - mysql -u root -e 'CREATE DATABASE keyv_test;'
+  - mysql -u root -e 'GRANT ALL PRIVILEGES ON keyv_test.* TO 'mysql'@'localhost';'
+script: npm run test:full
+after_success: npm run coverage
+notifications:
+  email:
+    on_success: never
diff --git a/test/manager/__snapshots__/index.spec.js.snap b/test/manager/__snapshots__/index.spec.js.snap
index 9104f880ddc2272970a548f621102e3938fe5ebe..90f1e0df3c12424dd62861efc17a83563b57a7c7 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 .travis.yml files 1`] = `
+Array [
+  ".travis.yml",
+]
+`;
+
 exports[`manager detectPackageFiles(config) finds Dockerfiles 1`] = `
 Array [
   "Dockerfile",
diff --git a/test/manager/__snapshots__/resolve.spec.js.snap b/test/manager/__snapshots__/resolve.spec.js.snap
index 2502e7d1b448f1870d11aeea843540bfc8cc555e..a2e4f232f3e80f5c210d2f70bca83d7c1bab555f 100644
--- a/test/manager/__snapshots__/resolve.spec.js.snap
+++ b/test/manager/__snapshots__/resolve.spec.js.snap
@@ -366,6 +366,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -466,6 +509,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -847,6 +891,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -958,6 +1045,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -968,7 +1056,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
 }
 `;
 
-exports[`manager/resolve resolvePackageFiles() detects meteor and docker 1`] = `
+exports[`manager/resolve resolvePackageFiles() detects meteor and docker and travis 1`] = `
 Object {
   "assignees": Array [],
   "autodiscover": false,
@@ -1334,6 +1422,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -1562,6 +1693,52 @@ Please make sure the following warnings are safe to ignore:
 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 {
+      "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+      "content": "hello: world
+",
+      "enabled": false,
+      "packageFile": ".travis.yml",
+      "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+      "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+      "supportPolicy": Array [
+        "lts",
+      ],
+    },
   ],
   "packageNames": Array [],
   "packagePatterns": Array [],
@@ -1653,6 +1830,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -2029,6 +2207,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -2137,6 +2358,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -2513,6 +2735,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -2613,6 +2878,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -2623,7 +2889,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
 }
 `;
 
-exports[`manager/resolve resolvePackageFiles() skips docker if no content or no match 1`] = `
+exports[`manager/resolve resolvePackageFiles() skips if no content or no match 1`] = `
 Object {
   "assignees": Array [],
   "autodiscover": false,
@@ -2989,6 +3255,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -3089,6 +3398,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -3474,6 +3784,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "minor": Object {},
   "monorepoPackages": Array [],
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -3574,6 +3927,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
diff --git a/test/manager/index.spec.js b/test/manager/index.spec.js
index acf6bd17fb194978039b88b6666431b94d836970..8340b2142cc50390e3ec1abc5727cc5150f4914e 100644
--- a/test/manager/index.spec.js
+++ b/test/manager/index.spec.js
@@ -3,6 +3,7 @@ const manager = require('../../lib/manager');
 const npmUpdater = require('../../lib/manager/npm/update');
 const meteorUpdater = require('../../lib/manager/meteor/update');
 const dockerUpdater = require('../../lib/manager/docker/update');
+const nodeUpdater = require('../../lib/manager/node/update');
 
 const { getUpdatedPackageFiles } = manager;
 
@@ -59,6 +60,16 @@ describe('manager', () => {
       expect(res).toMatchSnapshot();
       expect(res).toHaveLength(1);
     });
+    it('finds .travis.yml files', async () => {
+      config.node.enabled = true;
+      platform.getFileList.mockReturnValueOnce([
+        '.travis.yml',
+        'other/.travis.yml',
+      ]);
+      const res = await manager.detectPackageFiles(config);
+      expect(res).toMatchSnapshot();
+      expect(res).toHaveLength(1);
+    });
     it('skips Dockerfiles with no content', async () => {
       platform.getFileList.mockReturnValueOnce(['Dockerfile']);
       platform.getFile.mockReturnValueOnce(null);
@@ -87,6 +98,7 @@ describe('manager', () => {
       npmUpdater.setNewValue = jest.fn();
       dockerUpdater.setNewValue = jest.fn();
       meteorUpdater.setNewValue = jest.fn();
+      nodeUpdater.setNewValue = jest.fn();
     });
     it('returns empty if lock file maintenance', async () => {
       config.upgrades = [{ type: 'lockFileMaintenance' }];
@@ -119,15 +131,18 @@ describe('manager', () => {
         { packageFile: 'package.json' },
         { packageFile: 'Dockerfile' },
         { packageFile: 'packages/foo/package.js' },
+        { packageFile: '.travis.yml' },
       ];
       platform.getFile.mockReturnValueOnce('old content 1');
       platform.getFile.mockReturnValueOnce('old content 1');
       platform.getFile.mockReturnValueOnce('old content 2');
       platform.getFile.mockReturnValueOnce('old content 3');
+      platform.getFile.mockReturnValueOnce('old travis');
       npmUpdater.setNewValue.mockReturnValueOnce('new content 1');
       npmUpdater.setNewValue.mockReturnValueOnce('new content 1+');
       dockerUpdater.setNewValue.mockReturnValueOnce('new content 2');
       meteorUpdater.setNewValue.mockReturnValueOnce('old content 3');
+      nodeUpdater.setNewValue.mockReturnValueOnce('old travis');
       const res = await getUpdatedPackageFiles(config);
       expect(res.updatedPackageFiles).toHaveLength(2);
     });
diff --git a/test/manager/node/__snapshots__/package.spec.js.snap b/test/manager/node/__snapshots__/package.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..57e49a7105c62012758384b46c5982310a8410dc
--- /dev/null
+++ b/test/manager/node/__snapshots__/package.spec.js.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`lib/workers/package/node getPackageUpdates returns result if needing updates 1`] = `
+Array [
+  Object {
+    "newVersions": Array [
+      "8",
+      "6",
+      "4",
+    ],
+  },
+]
+`;
diff --git a/test/manager/node/__snapshots__/update.spec.js.snap b/test/manager/node/__snapshots__/update.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..3b798eea389e1bc9b3c4bdb206805797d7758869
--- /dev/null
+++ b/test/manager/node/__snapshots__/update.spec.js.snap
@@ -0,0 +1,27 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/node/update setNewValue falls back to 2 spaces 1`] = `"hello: world"`;
+
+exports[`manager/node/update setNewValue updates values 1`] = `
+"dist: trusty
+language: node_js
+node_js:
+  - '6'
+  - '8'
+services:
+  - redis-server
+  - mongodb
+  - mysql
+addons:
+  postgresql: '9.5'
+before_script:
+  - psql -c 'create database keyv_test;' -U postgres
+  - mysql -u root -e 'CREATE DATABASE keyv_test;'
+  - mysql -u root -e 'GRANT ALL PRIVILEGES ON keyv_test.* TO 'mysql'@'localhost';'
+script: npm run test:full
+after_success: npm run coverage
+notifications:
+  email:
+    on_success: never
+"
+`;
diff --git a/test/manager/node/extract.spec.js b/test/manager/node/extract.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..080077b615fd11276cafdf279ac2f5d831bca5e2
--- /dev/null
+++ b/test/manager/node/extract.spec.js
@@ -0,0 +1,14 @@
+const { extractDependencies } = require('../../../lib/manager/node/extract');
+
+describe('lib/manager/node/extract', () => {
+  describe('extractDependencies()', () => {
+    let config;
+    beforeEach(() => {
+      config = {};
+    });
+    it('returns empty if fails to pass', () => {
+      const res = extractDependencies('blahhhhh:foo:@what\n', config);
+      expect(res).toEqual([]);
+    });
+  });
+});
diff --git a/test/manager/node/package.spec.js b/test/manager/node/package.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..25de5403222a205c60f83cf74742f118f9242a3f
--- /dev/null
+++ b/test/manager/node/package.spec.js
@@ -0,0 +1,26 @@
+const node = require('../../../lib/manager/node/package');
+const defaultConfig = require('../../../lib/config/defaults').getConfig();
+
+describe('lib/workers/package/node', () => {
+  describe('getPackageUpdates', () => {
+    let config;
+    beforeEach(() => {
+      config = {
+        ...defaultConfig,
+      };
+    });
+    it('returns empty if no supportPolicy array', async () => {
+      expect(await node.getPackageUpdates(config)).toEqual([]);
+    });
+    it('returns empty if matching', async () => {
+      config.currentVersions = ['6', '8'];
+      config.supportPolicy = ['lts_active'];
+      expect(await node.getPackageUpdates(config)).toEqual([]);
+    });
+    it('returns result if needing updates', async () => {
+      config.currentVersions = ['6', '8'];
+      config.supportPolicy = ['lts'];
+      expect(await node.getPackageUpdates(config)).toMatchSnapshot();
+    });
+  });
+});
diff --git a/test/manager/node/update.spec.js b/test/manager/node/update.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..84b0ab6f5aa94329ca64a69a826cee5eeeb527ed
--- /dev/null
+++ b/test/manager/node/update.spec.js
@@ -0,0 +1,34 @@
+const fs = require('fs');
+const path = require('path');
+const nodefile = require('../../../lib/manager/node/update');
+
+const content = fs.readFileSync(
+  path.resolve('test/_fixtures/node/travis.yml'),
+  'utf8'
+);
+
+describe('manager/node/update', () => {
+  describe('setNewValue', () => {
+    it('updates values', () => {
+      const upgrade = {
+        newVersions: ['6', '8'],
+      };
+      const res = nodefile.setNewValue(content, upgrade);
+      expect(res).toMatchSnapshot();
+    });
+    it('falls back to 2 spaces', () => {
+      const upgrade = {
+        newVersions: ['6', '8'],
+      };
+      const res = nodefile.setNewValue('hello: world', upgrade);
+      expect(res).toMatchSnapshot();
+    });
+    it('returns null if error', () => {
+      const upgrade = {
+        newVersions: '6',
+      };
+      const res = nodefile.setNewValue(content, upgrade);
+      expect(res).toBe(null);
+    });
+  });
+});
diff --git a/test/manager/resolve.spec.js b/test/manager/resolve.spec.js
index 638f5c93ae193f5a3626a3fc0fae317ee4b340bc..39cf9366f78608b18674dbcb9f6de8f7bfdb94b2 100644
--- a/test/manager/resolve.spec.js
+++ b/test/manager/resolve.spec.js
@@ -64,14 +64,15 @@ describe('manager/resolve', () => {
       expect(res).toMatchSnapshot();
       expect(res.warnings).toHaveLength(0);
     });
-    it('detects meteor and docker', async () => {
-      config.packageFiles = ['package.js', 'Dockerfile'];
+    it('detects meteor and docker and travis', async () => {
+      config.packageFiles = ['package.js', 'Dockerfile', '.travis.yml'];
       platform.getFile.mockReturnValueOnce('# comment\nFROM node:8\n'); // Dockerfile
+      platform.getFile.mockReturnValueOnce('hello: world\n'); // Dockerfile
       const res = await resolvePackageFiles(config);
       expect(res).toMatchSnapshot();
     });
-    it('skips docker if no content or no match', async () => {
-      config.packageFiles = ['Dockerfile', 'other/Dockerfile'];
+    it('skips if no content or no match', async () => {
+      config.packageFiles = ['Dockerfile', 'other/Dockerfile', '.travis.yml'];
       platform.getFile.mockReturnValueOnce('# comment\n'); // Dockerfile
       const res = await resolvePackageFiles(config);
       expect(res).toMatchSnapshot();
diff --git a/test/workers/dep-type/index.spec.js b/test/workers/dep-type/index.spec.js
index 8bbd571dfaf28868d4088810987710d3ac059ff8..20dfeeceba46e0633162322840f48e4583e3f26f 100644
--- a/test/workers/dep-type/index.spec.js
+++ b/test/workers/dep-type/index.spec.js
@@ -57,6 +57,15 @@ describe('lib/workers/dep-type/index', () => {
       const res = await depTypeWorker.renovateDepType(content, config);
       expect(res).toHaveLength(6);
     });
+    it('returns upgrades for travis', async () => {
+      config.packageFile = '.travis.yml';
+      const content = fs.readFileSync(
+        path.resolve('test/_fixtures/node/travis.yml'),
+        'utf8'
+      );
+      const res = await depTypeWorker.renovateDepType(content, config);
+      expect(res).toHaveLength(1);
+    });
     it('handles malformed meteor', async () => {
       config.packageFile = 'package.js';
       const content = 'blah';
diff --git a/test/workers/package-file/index.spec.js b/test/workers/package-file/index.spec.js
index 6b2ba06d4807bbdeb983937ad36d0fd087a924db..8feeb39674f85fa94b36f3d07ea0fb5a7c545550 100644
--- a/test/workers/package-file/index.spec.js
+++ b/test/workers/package-file/index.spec.js
@@ -76,6 +76,27 @@ describe('packageFileWorker', () => {
       expect(res).toHaveLength(2);
     });
   });
+  describe('renovateNodeFile(config)', () => {
+    let config;
+    beforeEach(() => {
+      config = {
+        ...defaultConfig,
+        packageFile: '.travis.yml',
+        repoIsOnboarded: true,
+      };
+      depTypeWorker.renovateDepType.mockReturnValue([]);
+    });
+    it('returns empty if disabled', async () => {
+      config.enabled = false;
+      const res = await packageFileWorker.renovateNodeFile(config);
+      expect(res).toEqual([]);
+    });
+    it('returns upgrades', async () => {
+      depTypeWorker.renovateDepType.mockReturnValueOnce([{}]);
+      const res = await packageFileWorker.renovateNodeFile(config);
+      expect(res).toHaveLength(1);
+    });
+  });
   describe('renovateDockerfile', () => {
     let config;
     beforeEach(() => {
diff --git a/test/workers/package/__snapshots__/index.spec.js.snap b/test/workers/package/__snapshots__/index.spec.js.snap
index af1a7d707d5f4cae22069d1d99f6edc420b01f79..1547662e429c8f60c9f4b8f7cd8fc563d0ceab65 100644
--- a/test/workers/package/__snapshots__/index.spec.js.snap
+++ b/test/workers/package/__snapshots__/index.spec.js.snap
@@ -147,6 +147,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommitScope": "deps",
   "semanticCommitType": "chore",
   "semanticCommits": null,
+  "supportPolicy": Array [],
   "timezone": null,
   "type": "pin",
   "unpublishSafe": false,
diff --git a/test/workers/package/index.spec.js b/test/workers/package/index.spec.js
index 91943ae1f7ed547321ad7f1d2231f413cc9c9d88..c7e2d48b9aa156af95f471d80bf5b8990625c31e 100644
--- a/test/workers/package/index.spec.js
+++ b/test/workers/package/index.spec.js
@@ -4,9 +4,11 @@ const configParser = require('../../../lib/config');
 
 const docker = require('../../../lib/manager/docker/package');
 const npm = require('../../../lib/manager/npm/package');
+const node = require('../../../lib/manager/node/package');
 
 jest.mock('../../../lib/manager/docker/package');
 jest.mock('../../../lib/manager/npm/package');
+jest.mock('../../../lib/manager/node/package');
 
 describe('lib/workers/package/index', () => {
   describe('renovatePackage(config)', () => {
@@ -33,6 +35,12 @@ describe('lib/workers/package/index', () => {
       const res = await pkgWorker.renovatePackage(config);
       expect(res).toMatchObject([]);
     });
+    it('calls node', async () => {
+      node.getPackageUpdates.mockReturnValueOnce([]);
+      config.packageFile = '.travis.yml';
+      const res = await pkgWorker.renovatePackage(config);
+      expect(res).toMatchObject([]);
+    });
     it('maps and filters type', async () => {
       config.packageFile = 'package.json';
       config.major.enabled = false;
diff --git a/test/workers/repository/updates/__snapshots__/branchify.spec.js.snap b/test/workers/repository/updates/__snapshots__/branchify.spec.js.snap
index 078787f322863ff15e0300e019af6d5b80be5477..7c1271a40786dbc77717f086067d3e29ad367c5f 100644
--- a/test/workers/repository/updates/__snapshots__/branchify.spec.js.snap
+++ b/test/workers/repository/updates/__snapshots__/branchify.spec.js.snap
@@ -410,6 +410,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   },
   "minor": Object {},
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -510,6 +553,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -923,6 +967,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   },
   "minor": Object {},
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -1023,6 +1110,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -1442,6 +1530,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   },
   "minor": Object {},
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -1542,6 +1673,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -1949,6 +2081,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   },
   "minor": Object {},
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -2049,6 +2224,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
@@ -2451,6 +2627,49 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   },
   "minor": Object {},
   "multipleMajorPrs": false,
+  "node": Object {
+    "branchName": "{{branchPrefix}}node-{{depNameSanitized}}",
+    "enabled": false,
+    "prBody": "This Pull Request updates \`{{depName}}\` versions from \`{{currentVersions}}\` to \`{{newVersions}}\`. This is according to the configured node.js support policy \\"{{supportPolicy}}\\".
+
+{{#if schedule}}
+**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times.
+{{/if}}
+
+{{#if hasErrors}}
+
+---
+
+### Errors
+
+Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.
+
+{{#each errors as |error|}}
+-   \`{{error.depName}}\`: {{error.message}}
+{{/each}}
+{{/if}}
+
+{{#if hasWarnings}}
+
+---
+
+### Warnings
+
+Please make sure the following warnings are safe to ignore:
+
+{{#each warnings as |warning|}}
+-   \`{{warning.depName}}\`: {{warning.message}}
+{{/each}}
+{{/if}}
+
+---
+
+This PR has been generated by [Renovate Bot](https://renovateapp.com).",
+    "prTitle": "Update {{depName}} versions to [{{newVersions}}]",
+    "supportPolicy": Array [
+      "lts",
+    ],
+  },
   "npm": Object {
     "enabled": true,
     "pin": Object {
@@ -2552,6 +2771,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).",
   "semanticCommits": null,
   "separateMajorReleases": true,
   "separatePatchReleases": false,
+  "supportPolicy": Array [],
   "timezone": null,
   "token": null,
   "unpublishSafe": false,
diff --git a/test/workers/repository/updates/determine.spec.js b/test/workers/repository/updates/determine.spec.js
index 6311d37432c49d010e6fc72175b9452faaa7242e..53fc56c8c663e62b379a9f1121f562321263fefa 100644
--- a/test/workers/repository/updates/determine.spec.js
+++ b/test/workers/repository/updates/determine.spec.js
@@ -38,6 +38,9 @@ describe('workers/repository/updates/determine', () => {
         {
           packageFile: 'frontend/package.js',
         },
+        {
+          packageFile: '.travis.yml',
+        },
       ];
       packageFileWorker.renovateDockerfile.mockReturnValueOnce([
         { depName: 'a' },
@@ -49,8 +52,9 @@ describe('workers/repository/updates/determine', () => {
       packageFileWorker.renovateMeteorPackageFile.mockReturnValueOnce([
         { foo: 'd' },
       ]);
+      packageFileWorker.renovateNodeFile.mockReturnValueOnce([{ foo: 'e' }]);
       const res = await determineRepoUpgrades(config);
-      expect(res.upgrades).toHaveLength(4);
+      expect(res.upgrades).toHaveLength(5);
     });
   });
 });
diff --git a/yarn.lock b/yarn.lock
index 6fb4f470a5a49f6c840564afb077e57290a5426b..179fed9abcb1102b04749ed18514b4ba7387a0ba 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1216,16 +1216,16 @@ delegates@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
 
+detect-indent@5.0.0, detect-indent@~5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
+
 detect-indent@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
   dependencies:
     repeating "^2.0.0"
 
-detect-indent@~5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
-
 detect-libc@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1"
@@ -2896,7 +2896,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
 
-js-yaml@^3.7.0, js-yaml@^3.9.1:
+js-yaml@3.10.0, js-yaml@^3.7.0, js-yaml@^3.9.1:
   version "3.10.0"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
   dependencies: