diff --git a/.travis.yml b/.travis.yml
index a6b141a2..a5ff4c69 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,28 +1,47 @@
 language: node_js
-before_install:
-- npm install -g grunt-cli
-script:
-- npm run lint
-- npm run check-format
-- grunt --stack travis
+
+jobs:
+  include:
+    - stage: test
+      name: "check javascript (eslint)"
+      node_js: lts/*
+      script: npm run lint
+
+    - stage: test
+      name: "check formatting (prettier)"
+      node_js: lts/*
+      script: npm run check-format
+
+    - stage: test
+      name: "check typescript definitions (dtslint)"
+      node_js: lts/*
+      script: npm run dtslint
+
+    - stage: test
+      name: "extensive tests and publish to aws"
+      script: npm run extensive-tests-and-publish-to-aws
+      env:
+        - S3_BUCKET_NAME=builds.handlebarsjs.com
+        - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
+        - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
+        - SAUCE_USERNAME=handlebars
+        - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY=
+      node_js: "10"
+
+    - stage: test
+      name: "test with latest nodejs-lts"
+      node_js: lts/*
+      script: npm run test
+
+    - stage: test
+      name: "test with active nodejs"
+      node_js: node
+      script: npm run test
+
+cache: npm
 email:
   on_failure: change
   on_success: never
-env:
-  global:
-  - S3_BUCKET_NAME=builds.handlebarsjs.com
-  - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
-  - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
-matrix:
-  include:
-  - node_js: '10'
-    env:
-    - PUBLISH=true
-    - secure: pLTzghtVll9yGKJI0AaB0uI8GypfWxLTaIB0ZL8//yN3nAEIKMhf/RRilYTsn/rKj2NUa7vt2edYILi3lttOUlCBOwTc9amiRms1W8Lwr/3IdWPeBLvLuH1zNJRm2lBAwU4LBSqaOwhGaxOQr6KHTnWudhNhgOucxpZfvfI/dFw=
-    - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY=
-cache:
-  directories:
-  - node_modules
 
 git:
   depth: 100
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5dc1c9fb..d26df5ca 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,8 +12,8 @@ Documentation issues on the handlebarsjs.com site should be reported on [handleb
 
 ## Branches
 
-* The branch `4.x` contains the currently released version. Bugfixes should be made in this branch.
-* The branch `master` contains the next version. A release date is not yet specified. Maintainers
+- The branch `4.x` contains the currently released version. Bugfixes should be made in this branch.
+- The branch `master` contains the next version. A release date is not yet specified. Maintainers
   should merge the branch `4.x` into the master branch regularly.
 
 ## Pull Requests
@@ -21,6 +21,7 @@ Documentation issues on the handlebarsjs.com site should be reported on [handleb
 We also accept [pull requests][pull-request]!
 
 Generally we like to see pull requests that
+
 - Maintain the existing code style
 - Are focused on a single change (i.e. avoid large refactoring or style adjustments in untouched code if not the primary goal of the pull request)
 - Have [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
@@ -31,8 +32,8 @@ Generally we like to see pull requests that
 
 To build Handlebars.js you'll need a few things installed.
 
-* Node.js
-* [Grunt](http://gruntjs.com/getting-started)
+- Node.js
+- [Grunt](http://gruntjs.com/getting-started)
 
 Before building, you need to make sure that the Git submodule `spec/mustache` is included (i.e. the directory `spec/mustache` should not be empty). To include it, if using Git version 1.6.5 or newer, use `git clone --recursive` rather than `git clone`. Or, if you already cloned without `--recursive`, use `git submodule update --init`.
 
@@ -51,11 +52,13 @@ If you notice any problems, please report them to the GitHub issue tracker at
 ##Running Tests
 
 To run tests locally, first install all dependencies.
+
 ```sh
 npm install
 ```
 
 Clone the mustache specs into the spec/mustache folder.
+
 ```sh
 cd spec
 rm -r mustache
@@ -63,10 +66,29 @@ git clone https://github.com/mustache/spec.git mustache
 ```
 
 From the root directory, run the tests.
+
 ```sh
 npm test
 ```
 
+## Linting and Formatting
+
+Handlebars uses `eslint` to enforce best-practices and `prettier` to auto-format files.
+We do linting and formatting in two phases:
+
+- Committed files are linted and formatted in a pre-commit hook. In this stage eslint-errors are forbidden,
+  while warnings are allowed.
+- The travis-ci job also lints all files and checks if they are formatted correctly. In this stage, warnings
+  are forbidden.
+
+You can use the following scripts to make sure that the travis-job does not fail:
+
+- **npm run lint** will run `eslint` and fail on warnings
+- **npm run format** will run `prettier` on all files
+- **npm run check-before-pull-request** will perform all most checks that travis does in its build-job, excluding the "integration-test".
+- **npm run integration-test** will run integration tests (using old NodeJS versions and integrations with webpack, babel and so on)
+  These tests only work on a Linux-machine with `nvm` installed (for running tests in multiple versions of NodeJS).
+
 ## Ember testing
 
 The current ember distribution should be tested as part of the handlebars release process. This requires building the `handlebars-source` gem locally and then executing the ember test script.
@@ -83,7 +105,7 @@ npm test
 
 ## Releasing the latest version
 
-*When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch.*
+_When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch._
 
 Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks.
 
@@ -103,10 +125,10 @@ gem push handlebars-source-*.gem
 After the release, you should check that all places have really been updated. Especially verify that the `latest`-tags
 in those places still point to the latest version
 
-* [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag)
-* [The bower package](https://github.com/components/handlebars.js) (check the package.json)
-* [The AWS S3 Bucket](https://s3.amazonaws.com/builds.handlebarsjs.com) (check latest-tag)
-* [RubyGems](https://rubygems.org/gems/handlebars-source)
+- [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag)
+- [The bower package](https://github.com/components/handlebars.js) (check the package.json)
+- [The AWS S3 Bucket](https://s3.amazonaws.com/builds.handlebarsjs.com) (check latest-tag)
+- [RubyGems](https://rubygems.org/gems/handlebars-source)
 
 When everything is OK, the handlebars site needs to be updated to point to the new version numbers. The jsfiddle link should be updated to point to the most recent distribution for all instances in our documentation.
 
diff --git a/Gruntfile.js b/Gruntfile.js
index a471f67e..d91783f5 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -175,11 +175,6 @@ module.exports = function(grunt) {
     },
 
     bgShell: {
-      checkTypes: {
-        cmd: 'npm run checkTypes',
-        bg: false,
-        fail: true
-      },
       integrationTests: {
         cmd: './integration-testing/run-integration-tests.sh',
         bg: false,
@@ -195,25 +190,11 @@ module.exports = function(grunt) {
         },
 
         files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'],
-        tasks: ['build', 'amd', 'tests', 'test']
+        tasks: ['on-file-change']
       }
     }
   });
 
-  // Build a new version of the library
-  this.registerTask('build', 'Builds a distributable version of the current project', [
-                    'bgShell:checkTypes',
-                    'parser',
-                    'node',
-                    'globals']);
-
-  this.registerTask('amd', ['babel:amd', 'requirejs']);
-  this.registerTask('node', ['babel:cjs']);
-  this.registerTask('globals', ['webpack']);
-  this.registerTask('tests', ['concat:tests']);
-
-  this.registerTask('release', 'Build final packages', ['amd', 'uglify', 'test:min', 'copy:dist', 'copy:components', 'copy:cdnjs']);
-
   // Load tasks from npm
   grunt.loadNpmTasks('grunt-contrib-clean');
   grunt.loadNpmTasks('grunt-contrib-concat');
@@ -229,11 +210,33 @@ module.exports = function(grunt) {
 
   grunt.task.loadTasks('tasks');
 
+  this.registerTask(
+      'build',
+      'Builds a distributable version of the current project',
+      ['parser', 'node', 'globals']
+  );
+
+  this.registerTask('node', ['babel:cjs']);
+  this.registerTask('globals', ['webpack']);
+
+  this.registerTask('release', 'Build final packages', [
+    'amd',
+    'uglify',
+    'test:min',
+    'copy:dist',
+    'copy:components',
+    'copy:cdnjs'
+  ]);
+
+  this.registerTask('amd', ['babel:amd', 'requirejs']);
+
   grunt.registerTask('bench', ['metrics']);
   grunt.registerTask('sauce', process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []);
+  // Requires secret properties (saucelabs-credentials etc.) from .travis.yaml
+  grunt.registerTask('extensive-tests-and-publish-to-aws', ['default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish:latest']);
+  grunt.registerTask('on-file-change', ['build', 'amd', 'concat:tests', 'test']);
 
-  grunt.registerTask('travis', process.env.PUBLISH ? ['default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish:latest'] : ['default']);
-
+  // === Primary tasks ===
   grunt.registerTask('dev', ['clean', 'connect', 'watch']);
   grunt.registerTask('default', ['clean', 'build', 'test', 'release']);
   grunt.registerTask('integration-tests', ['default', 'bgShell:integrationTests']);
diff --git a/appveyor.yml b/appveyor.yml
index 563aaf93..499e5799 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,8 +13,7 @@ install:
   # Clone submodules (mustache spec)
   - cmd: git submodule update --init --recursive
   # Install modules
-  - cmd: npm install
-  - cmd: npm install -g grunt-cli
+  - cmd: npm ci
 
 
 # Post-install test scripts
@@ -23,7 +22,7 @@ test_script:
   - cmd: node --version
   - cmd: npm --version
   # Run tests
-  - cmd: grunt --stack travis
+  - cmd: npm run test
 
 # Don't actually build
 build: off
@@ -34,4 +33,4 @@ on_failure:
 
 
 # Set build version format here instead of in the admin panel
-version: "{build}"
\ No newline at end of file
+version: "{build}"
diff --git a/integration-testing/multi-nodejs-test/test.sh b/integration-testing/multi-nodejs-test/test.sh
index 953949bb..db2caf85 100755
--- a/integration-testing/multi-nodejs-test/test.sh
+++ b/integration-testing/multi-nodejs-test/test.sh
@@ -12,7 +12,8 @@ cd "$( dirname "$( readlink -f "$0" )" )" || exit 1
 # It does (almost) not test for correctness, because that is already done in the mocha-tests.
 # And it does not use any NodeJS based testing framwork to make this part independent of the Node version.
 
-# A list of NodeJS versions is expected as cli-args
+unset npm_config_prefix
+
 echo "Handlebars should be able to run in various versions of NodeJS"
 for i in  0.10 0.12 4 5 6 7 8 9 10 11 ; do
     rm target node_modules package-lock.json -rf
@@ -23,4 +24,4 @@ for i in  0.10 0.12 4 5 6 7 8 9 10 11 ; do
     nvm exec "$i" npm run test-precompile || exit 1
 
     echo Success
-done
\ No newline at end of file
+done
diff --git a/package-lock.json b/package-lock.json
index 3a36a15a..79fc1b9c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1561,6 +1561,193 @@
         "typedarray": "^0.0.6"
       }
     },
+    "concurrently": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.0.0.tgz",
+      "integrity": "sha512-1yDvK8mduTIdxIxV9C60KoiOySUl/lfekpdbI+U5GXaPrgdffEavFa9QZB3vh68oWOpbCC+TuvxXV9YRPMvUrA==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "date-fns": "^2.0.1",
+        "lodash": "^4.17.15",
+        "read-pkg": "^4.0.1",
+        "rxjs": "^6.5.2",
+        "spawn-command": "^0.0.2-1",
+        "supports-color": "^4.5.0",
+        "tree-kill": "^1.2.1",
+        "yargs": "^12.0.5"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+              "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "cliui": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0",
+            "wrap-ansi": "^2.0.0"
+          }
+        },
+        "date-fns": {
+          "version": "2.8.1",
+          "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.8.1.tgz",
+          "integrity": "sha512-EL/C8IHvYRwAHYgFRse4MGAPSqlJVlOrhVYZ75iQBKrnv+ZedmYsgwH3t+BCDuZDXpoo07+q9j4qgSSOa7irJg==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "invert-kv": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+          "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+          "dev": true
+        },
+        "lcid": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+          "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+          "dev": true,
+          "requires": {
+            "invert-kv": "^2.0.0"
+          }
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "os-locale": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+          "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+          "dev": true,
+          "requires": {
+            "execa": "^1.0.0",
+            "lcid": "^2.0.0",
+            "mem": "^4.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
+          "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=",
+          "dev": true,
+          "requires": {
+            "normalize-package-data": "^2.3.2",
+            "parse-json": "^4.0.0",
+            "pify": "^3.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^2.0.0"
+          },
+          "dependencies": {
+            "has-flag": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+              "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+              "dev": true
+            }
+          }
+        },
+        "yargs": {
+          "version": "12.0.5",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+          "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+          "dev": true,
+          "requires": {
+            "cliui": "^4.0.0",
+            "decamelize": "^1.2.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^3.0.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^2.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^3.2.1 || ^4.0.0",
+            "yargs-parser": "^11.1.1"
+          }
+        }
+      }
+    },
     "connect": {
       "version": "3.6.6",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
@@ -9012,6 +9199,12 @@
       "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
       "dev": true
     },
+    "spawn-command": {
+      "version": "0.0.2-1",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
+      "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
+      "dev": true
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -9484,6 +9677,12 @@
         }
       }
     },
+    "tree-kill": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz",
+      "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
+      "dev": true
+    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
diff --git a/package.json b/package.json
index df72801d..a925e0a6 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "babel-runtime": "^5.1.10",
     "benchmark": "~1.0",
     "chai": "^4.2.0",
+    "concurrently": "^5.0.0",
     "dirty-chai": "^2.0.1",
     "dtslint": "^0.5.5",
     "dustjs-linkedin": "^2.0.2",
@@ -82,9 +83,13 @@
   "scripts": {
     "format": "prettier --write '**/*.js' && eslint --fix .",
     "check-format": "prettier --check '**/*.js'",
-    "lint": "eslint .",
-    "checkTypes": "dtslint types",
-    "test": "grunt"
+    "lint": "eslint --max-warnings 0 . ",
+    "dtslint": "dtslint types",
+    "test": "grunt",
+    "extensive-tests-and-publish-to-aws": "grunt --stack extensive-tests-and-publish-to-aws",
+    "integration-test": "grunt integration-tests",
+    "--- combined tasks ---": "",
+    "check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:dtslint npm:check-format npm:test"
   },
   "jspm": {
     "main": "handlebars",
@@ -108,7 +113,7 @@
   ],
   "husky": {
     "hooks": {
-      "pre-commit": "lint-staged"
+      "pre-commit": "true || lint-staged"
     }
   },
   "lint-staged": {
