diff --git a/.all-contributorsrc b/.all-contributorsrc
index f6cf697b..78b7aad7 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -188,6 +188,25 @@
         "code",
         "test"
       ]
+    },
+    {
+      "login": "the-ult",
+      "name": "Arjen",
+      "avatar_url": "https://avatars.githubusercontent.com/u/4863062?v=4",
+      "profile": "https://github.com/the-ult",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "lacolaco",
+      "name": "Suguru Inatomi",
+      "avatar_url": "https://avatars.githubusercontent.com/u/1529180?v=4",
+      "profile": "https://lacolaco.net",
+      "contributions": [
+        "code",
+        "ideas"
+      ]
     }
   ],
   "contributorsPerLine": 7,
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..b740f815
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,120 @@
+{
+  "root": true,
+  "ignorePatterns": ["**/*"],
+  "plugins": ["@nrwl/nx"],
+  "overrides": [
+    {
+      "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+      "parserOptions": {
+        "project": ["/tsconfig.*?.json"]
+      },
+      "rules": {
+        "@nrwl/nx/enforce-module-boundaries": [
+          "error",
+          {
+            "enforceBuildableLibDependency": true,
+            "allow": [],
+            "depConstraints": [
+              {
+                "sourceTag": "*",
+                "onlyDependOnLibsWithTags": ["*"]
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.ts", "*.tsx"],
+      "extends": ["plugin:@nrwl/nx/typescript"],
+      "rules": {}
+    },
+    {
+      "files": ["*.js", "*.jsx"],
+      "extends": ["plugin:@nrwl/nx/javascript"],
+      "rules": {}
+    },
+    {
+      "files": ["*.ts"],
+      "plugins": ["eslint-plugin-import", "@angular-eslint/eslint-plugin", "@typescript-eslint"],
+      "rules": {
+        "@typescript-eslint/consistent-type-definitions": "error",
+        "@typescript-eslint/dot-notation": "off",
+        "@typescript-eslint/naming-convention": "error",
+        "@typescript-eslint/no-shadow": [
+          "error",
+          {
+            "hoist": "all"
+          }
+        ],
+        "@typescript-eslint/no-unused-expressions": "error",
+        "@typescript-eslint/prefer-function-type": "error",
+        "@typescript-eslint/quotes": ["error", "single"],
+        "@typescript-eslint/type-annotation-spacing": "error",
+        "@typescript-eslint/no-explicit-any": "off",
+        "arrow-body-style": "error",
+        "brace-style": ["error", "1tbs"],
+        "curly": "error",
+        "eol-last": "error",
+        "eqeqeq": ["error", "smart"],
+        "guard-for-in": "error",
+        "id-blacklist": "off",
+        "id-match": "off",
+        "import/no-deprecated": "warn",
+        "no-bitwise": "error",
+        "no-caller": "error",
+        "no-console": [
+          "error",
+          {
+            "allow": [
+              "log",
+              "warn",
+              "dir",
+              "timeLog",
+              "assert",
+              "clear",
+              "count",
+              "countReset",
+              "group",
+              "groupEnd",
+              "table",
+              "dirxml",
+              "error",
+              "groupCollapsed",
+              "Console",
+              "profile",
+              "profileEnd",
+              "timeStamp",
+              "context"
+            ]
+          }
+        ],
+        "no-empty": "off",
+        "no-eval": "error",
+        "no-new-wrappers": "error",
+        "no-throw-literal": "error",
+        "no-undef-init": "error",
+        "no-underscore-dangle": "off",
+        "radix": "error",
+        "spaced-comment": [
+          "error",
+          "always",
+          {
+            "markers": ["/"]
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.spec.ts"],
+      "extends": ["plugin:testing-library/angular", "plugin:jest-dom/recommended"],
+      "rules": {
+        "testing-library/prefer-explicit-assert": "error"
+      }
+    },
+    {
+      "files": ["*.html"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 533b8363..0ee20df6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,12 +7,12 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest, windows-latest]
-        node: [12, 14]
+        node: [12, 14, 16]
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v1
+      - uses: actions/checkout@v2
       - name: use Node.js ${{ matrix.node-version }}
-        uses: actions/setup-node@v1
+        uses: actions/setup-node@v2
         with:
           node-version: ${{ matrix.node-version }}
       - name: install
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..2cbf2c26
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,53 @@
+# NPM Files
+package-lock.json
+migrations.json
+
+CHANGELOG.md
+
+#Ignore specific file types
+*.svg
+*.xml
+*.png
+*.jpg
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+# dependencies
+/node_modules
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/cSpell.json
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+testem.log
+/typings
+deployment.yaml
+
+# e2e
+/*e2e/*.js
+/*e2e/*.map
+
+# System Files
+.DS_Store
+Thumbs.db
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 53c5985d..8c53210b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,8 +10,7 @@ Hi there, thanks for being willing to contribute!
 
 ## Testing
 
-- Run `npm run test:lib` to test the library
-- Run `npm run test:app` to test the application
+- Run `npm run test` to test the library and the example application
 - Run `npm run build` to build the library
 
 ## Push changes
diff --git a/README.md b/README.md
index 3ed51be4..b542de69 100644
--- a/README.md
+++ b/README.md
@@ -139,7 +139,7 @@ describe('Counter', () => {
 });
 ```
 
-[See more examples](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/app/examples)
+[See more examples](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/src/app/examples)
 
 ## Installation
 
@@ -208,6 +208,8 @@ Thanks goes to these people ([emoji key][emojis]):
     <td align="center"><a href="http://wwww.reibo.be"><img src="https://avatars1.githubusercontent.com/u/1673799?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bo Vandersteene</b></sub></a><br /><a href="https://github.com/testing-library/angular-testing-library/commits?author=bovandersteene" title="Code">💻</a></td>
     <td align="center"><a href="https://github.com/jbchr"><img src="https://avatars1.githubusercontent.com/u/23141806?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Janek</b></sub></a><br /><a href="https://github.com/testing-library/angular-testing-library/commits?author=jbchr" title="Code">💻</a> <a href="https://github.com/testing-library/angular-testing-library/commits?author=jbchr" title="Tests">⚠️</a></td>
     <td align="center"><a href="https://github.com/GlebIrovich"><img src="https://avatars.githubusercontent.com/u/33176414?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gleb Irovich</b></sub></a><br /><a href="https://github.com/testing-library/angular-testing-library/commits?author=GlebIrovich" title="Code">💻</a> <a href="https://github.com/testing-library/angular-testing-library/commits?author=GlebIrovich" title="Tests">⚠️</a></td>
+    <td align="center"><a href="https://github.com/the-ult"><img src="https://avatars.githubusercontent.com/u/4863062?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Arjen</b></sub></a><br /><a href="https://github.com/testing-library/angular-testing-library/commits?author=the-ult" title="Code">💻</a></td>
+    <td align="center"><a href="https://lacolaco.net"><img src="https://avatars.githubusercontent.com/u/1529180?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Suguru Inatomi</b></sub></a><br /><a href="https://github.com/testing-library/angular-testing-library/commits?author=lacolaco" title="Code">💻</a> <a href="#ideas-lacolaco" title="Ideas, Planning, & Feedback">🤔</a></td>
   </tr>
 </table>
 
diff --git a/angular.json b/angular.json
index 85ad7d4e..46f51c32 100644
--- a/angular.json
+++ b/angular.json
@@ -1,12 +1,14 @@
 {
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
   "version": 1,
-  "newProjectRoot": "",
+  "cli": {
+    "analytics": false
+  },
+  "defaultProject": "example-app",
   "projects": {
     "example-app": {
-      "root": "",
-      "sourceRoot": "apps/example-app",
       "projectType": "application",
+      "root": "apps/example-app",
+      "sourceRoot": "apps/example-app/src",
       "prefix": "app",
       "schematics": {},
       "architect": {
@@ -15,12 +17,12 @@
           "options": {
             "aot": true,
             "outputPath": "dist/apps/example-app",
-            "index": "apps/example-app/index.html",
-            "main": "apps/example-app/main.ts",
-            "polyfills": "apps/example-app/polyfills.ts",
-            "tsConfig": "apps/example-app/tsconfig.json",
-            "assets": ["apps/example-app/favicon.ico", "apps/example-app/assets"],
-            "styles": ["apps/example-app/styles.css"],
+            "index": "apps/example-app/src/index.html",
+            "main": "apps/example-app/src/main.ts",
+            "polyfills": "apps/example-app/src/polyfills.ts",
+            "tsConfig": "apps/example-app/tsconfig.app.json",
+            "assets": ["apps/example-app/src/favicon.ico", "apps/example-app/src/assets"],
+            "styles": ["apps/example-app/src/styles.css"],
             "scripts": []
           },
           "configurations": {
@@ -33,8 +35,8 @@
               ],
               "fileReplacements": [
                 {
-                  "replace": "apps/example-app/environments/environment.ts",
-                  "with": "apps/example-app/environments/environment.prod.ts"
+                  "replace": "apps/example-app/src/environments/environment.ts",
+                  "with": "apps/example-app/src/environments/environment.prod.ts"
                 }
               ],
               "optimization": true,
@@ -46,7 +48,8 @@
               "vendorChunk": false,
               "buildOptimizer": true
             }
-          }
+          },
+          "outputs": ["{options.outputPath}"]
         },
         "serve": {
           "builder": "@angular-devkit/build-angular:dev-server",
@@ -66,19 +69,18 @@
           }
         },
         "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
+          "builder": "@nrwl/linter:eslint",
           "options": {
-            "tsConfig": ["apps/example-app/tsconfig.json", "apps/example-app/tsconfig.spec.json"],
-            "exclude": ["**/node_modules/**"]
+            "lintFilePatterns": ["apps/example-app/src/**/*.ts", "apps/example-app/src/**/*.html"]
           }
         },
         "test": {
           "builder": "@nrwl/jest:jest",
           "options": {
             "jestConfig": "apps/example-app/jest.config.js",
-            "tsConfig": "apps/example-app/tsconfig.spec.json",
-            "setupFile": "apps/example-app/test-setup.ts"
-          }
+            "setupFile": "apps/example-app/src/test-setup.ts"
+          },
+          "outputs": ["coverage/"]
         }
       }
     },
@@ -102,10 +104,13 @@
           }
         },
         "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
+          "builder": "@nrwl/linter:eslint",
           "options": {
-            "tsConfig": ["projects/testing-library/tsconfig.lib.json", "projects/testing-library/tsconfig.spec.json"],
-            "exclude": ["**/node_modules/**"]
+            "lintFilePatterns": [
+              "projects/testing-library/src/**/*.ts",
+              "projects/testing-library/src/**/*.html",
+              "projects/testing-library/src/**/*.html"
+            ]
           }
         },
         "build": {
@@ -116,12 +121,6 @@
               {
                 "command": "ng run testing-library:build-package"
               },
-              {
-                "command": "tsc -p ./projects/testing-library/migrations/tsconfig.migrations.json"
-              },
-              {
-                "command": "cpy ./projects/testing-library/migrations/migration.json ./dist/@testing-library/angular/migrations"
-              },
               {
                 "command": "cpy ./README.md ./dist/@testing-library/angular"
               }
@@ -132,9 +131,9 @@
           "builder": "@nrwl/jest:jest",
           "options": {
             "jestConfig": "projects/testing-library/jest.config.js",
-            "tsConfig": "projects/testing-library/tsconfig.spec.json",
             "setupFile": "projects/testing-library/test-setup.ts"
-          }
+          },
+          "outputs": ["coverage/projects/testing-library"]
         }
       }
     },
@@ -158,10 +157,13 @@
           }
         },
         "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
+          "builder": "@nrwl/linter:eslint",
           "options": {
-            "tsConfig": ["projects/jest-utils/tsconfig.lib.json", "projects/jest-utils/tsconfig.spec.json"],
-            "exclude": ["**/node_modules/**"]
+            "lintFilePatterns": [
+              "projects/jest-utils/src/**/*.ts",
+              "projects/jest-utils/src/**/*.html",
+              "projects/jest-utils/src/**/*.html"
+            ]
           }
         },
         "build": {
@@ -179,15 +181,11 @@
           "builder": "@nrwl/jest:jest",
           "options": {
             "jestConfig": "projects/jest-utils/jest.config.js",
-            "tsConfig": "projects/jest-utils/tsconfig.spec.json",
             "setupFile": "projects/jest-utils/test-setup.ts"
-          }
+          },
+          "outputs": ["coverage/projects/jest-utils"]
         }
       }
     }
-  },
-  "defaultProject": "example-app",
-  "cli": {
-    "analytics": false
   }
 }
diff --git a/apps/example-app/.browserslistrc b/apps/example-app/.browserslistrc
new file mode 100644
index 00000000..427441dc
--- /dev/null
+++ b/apps/example-app/.browserslistrc
@@ -0,0 +1,17 @@
+# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
+# For additional information regarding the format and rule options, please see:
+# https://github.com/browserslist/browserslist#queries
+
+# For the full list of supported browsers by the Angular framework, please see:
+# https://angular.io/guide/browser-support
+
+# You can see what browsers were selected by your queries by running:
+#   npx browserslist
+
+last 1 Chrome version
+last 1 Firefox version
+last 2 Edge major versions
+last 2 Safari major versions
+last 2 iOS major versions
+Firefox ESR
+not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
diff --git a/apps/example-app/.eslintrc.json b/apps/example-app/.eslintrc.json
new file mode 100644
index 00000000..2e1ae78b
--- /dev/null
+++ b/apps/example-app/.eslintrc.json
@@ -0,0 +1,37 @@
+{
+  "extends": ["../../.eslintrc.json"],
+  "ignorePatterns": ["!**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts"],
+      "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
+      "parserOptions": {
+        "project": ["apps/example-app/tsconfig.*?.json"]
+      },
+      "rules": {
+        "@angular-eslint/directive-selector": [
+          "error",
+          {
+            "type": "attribute",
+            "prefix": "app",
+            "style": "camelCase"
+          }
+        ],
+        "@angular-eslint/component-selector": [
+          "error",
+          {
+            "type": "element",
+            "prefix": "app",
+            "style": "kebab-case"
+          }
+        ]
+      },
+      "plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"]
+    },
+    {
+      "files": ["*.html"],
+      "extends": ["plugin:@nrwl/nx/angular-template"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/apps/example-app/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/app/examples/16-input-getter-setter.spec.ts
deleted file mode 100644
index 10e0e276..00000000
--- a/apps/example-app/app/examples/16-input-getter-setter.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { render, screen } from '@testing-library/angular';
-import { InputGetterSetter } from './16-input-getter-setter';
-
-test('should run logic in the input setter and getter', async () => {
-  await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
-  const valueControl = screen.getByTestId('value');
-  const getterValueControl = screen.getByTestId('value-getter');
-
-  expect(valueControl.textContent).toBe('I am value from setter Angular');
-  expect(getterValueControl.textContent).toBe('I am value from getter Angular');
-});
-
-test('should run logic in the input setter and getter while re-rendering', async () => {
-  const component = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
-  const valueControl = screen.getByTestId('value');
-  const getterValueControl = screen.getByTestId('value-getter');
-
-  expect(valueControl.textContent).toBe('I am value from setter Angular');
-  expect(getterValueControl.textContent).toBe('I am value from getter Angular');
-
-  await component.rerender({ value: 'React' });
-
-  expect(valueControl.textContent).toBe('I am value from setter React');
-  expect(getterValueControl.textContent).toBe('I am value from getter React');
-});
diff --git a/apps/example-app/jest.config.js b/apps/example-app/jest.config.js
index fe1aebd5..2be66c61 100644
--- a/apps/example-app/jest.config.js
+++ b/apps/example-app/jest.config.js
@@ -5,4 +5,5 @@ module.exports = {
     color: 'blue',
   },
   preset: '../../jest.preset.js',
+  setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
 };
diff --git a/apps/example-app/app/app-routing.module.ts b/apps/example-app/src/app/app-routing.module.ts
similarity index 100%
rename from apps/example-app/app/app-routing.module.ts
rename to apps/example-app/src/app/app-routing.module.ts
diff --git a/apps/example-app/app/app.component.css b/apps/example-app/src/app/app.component.css
similarity index 100%
rename from apps/example-app/app/app.component.css
rename to apps/example-app/src/app/app.component.css
diff --git a/apps/example-app/app/app.component.html b/apps/example-app/src/app/app.component.html
similarity index 100%
rename from apps/example-app/app/app.component.html
rename to apps/example-app/src/app/app.component.html
diff --git a/apps/example-app/app/app.component.ts b/apps/example-app/src/app/app.component.ts
similarity index 100%
rename from apps/example-app/app/app.component.ts
rename to apps/example-app/src/app/app.component.ts
diff --git a/apps/example-app/app/app.module.ts b/apps/example-app/src/app/app.module.ts
similarity index 100%
rename from apps/example-app/app/app.module.ts
rename to apps/example-app/src/app/app.module.ts
diff --git a/apps/example-app/app/examples/00-single-component.spec.ts b/apps/example-app/src/app/examples/00-single-component.spec.ts
similarity index 80%
rename from apps/example-app/app/examples/00-single-component.spec.ts
rename to apps/example-app/src/app/examples/00-single-component.spec.ts
index 460cae16..73e429bb 100644
--- a/apps/example-app/app/examples/00-single-component.spec.ts
+++ b/apps/example-app/src/app/examples/00-single-component.spec.ts
@@ -9,12 +9,12 @@ test('renders the current value and can increment and decrement', async () => {
   const decrementControl = screen.getByRole('button', { name: /decrement/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('0');
+  expect(valueControl).toHaveTextContent('0');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('2');
+  expect(valueControl).toHaveTextContent('2');
 
   fireEvent.click(decrementControl);
-  expect(valueControl.textContent).toBe('1');
+  expect(valueControl).toHaveTextContent('1');
 });
diff --git a/apps/example-app/app/examples/00-single-component.ts b/apps/example-app/src/app/examples/00-single-component.ts
similarity index 100%
rename from apps/example-app/app/examples/00-single-component.ts
rename to apps/example-app/src/app/examples/00-single-component.ts
diff --git a/apps/example-app/app/examples/01-nested-component.spec.ts b/apps/example-app/src/app/examples/01-nested-component.spec.ts
similarity index 83%
rename from apps/example-app/app/examples/01-nested-component.spec.ts
rename to apps/example-app/src/app/examples/01-nested-component.spec.ts
index bbaf9c37..8f3a242d 100644
--- a/apps/example-app/app/examples/01-nested-component.spec.ts
+++ b/apps/example-app/src/app/examples/01-nested-component.spec.ts
@@ -11,12 +11,12 @@ test('renders the current value and can increment and decrement', async () => {
   const decrementControl = screen.getByRole('button', { name: /decrement/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('0');
+  expect(valueControl).toHaveTextContent('0');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('2');
+  expect(valueControl).toHaveTextContent('2');
 
   fireEvent.click(decrementControl);
-  expect(valueControl.textContent).toBe('1');
+  expect(valueControl).toHaveTextContent('1');
 });
diff --git a/apps/example-app/app/examples/01-nested-component.ts b/apps/example-app/src/app/examples/01-nested-component.ts
similarity index 83%
rename from apps/example-app/app/examples/01-nested-component.ts
rename to apps/example-app/src/app/examples/01-nested-component.ts
index 8214c7a1..5b0faeb2 100644
--- a/apps/example-app/app/examples/01-nested-component.ts
+++ b/apps/example-app/src/app/examples/01-nested-component.ts
@@ -2,7 +2,7 @@ import { Component, Input, Output, EventEmitter } from '@angular/core';
 
 @Component({
   selector: 'app-button',
-  template: ` <button (click)="raise.emit()">{{ name }}</button> `,
+  template: ' <button (click)="raise.emit()">{{ name }}</button> ',
 })
 export class NestedButtonComponent {
   @Input() name: string;
@@ -11,7 +11,7 @@ export class NestedButtonComponent {
 
 @Component({
   selector: 'app-value',
-  template: ` <span data-testid="value">{{ value }}</span> `,
+  template: ' <span data-testid="value">{{ value }}</span> ',
 })
 export class NestedValueComponent {
   @Input() value: number;
diff --git a/apps/example-app/app/examples/02-input-output.spec.ts b/apps/example-app/src/app/examples/02-input-output.spec.ts
similarity index 83%
rename from apps/example-app/app/examples/02-input-output.spec.ts
rename to apps/example-app/src/app/examples/02-input-output.spec.ts
index 1f56e6c0..663d63e0 100644
--- a/apps/example-app/app/examples/02-input-output.spec.ts
+++ b/apps/example-app/src/app/examples/02-input-output.spec.ts
@@ -18,12 +18,12 @@ test('is possible to set input and listen for output', async () => {
   const sendControl = screen.getByRole('button', { name: /send/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('47');
+  expect(valueControl).toHaveTextContent('47');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('50');
+  expect(valueControl).toHaveTextContent('50');
 
   fireEvent.click(sendControl);
   expect(sendValue).toHaveBeenCalledTimes(1);
@@ -34,7 +34,7 @@ test('is possible to set input and listen for output with the template syntax',
   const sendSpy = jest.fn();
 
   await render(InputOutputComponent, {
-    template: `<app-fixture [value]="47" (sendValue)="sendValue($event)" (clicked)="clicked()"></app-fixture>`,
+    template: '<app-fixture [value]="47" (sendValue)="sendValue($event)" (clicked)="clicked()"></app-fixture>',
     componentProperties: {
       sendValue: sendSpy,
     },
@@ -44,12 +44,12 @@ test('is possible to set input and listen for output with the template syntax',
   const sendControl = screen.getByRole('button', { name: /send/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('47');
+  expect(valueControl).toHaveTextContent('47');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('50');
+  expect(valueControl).toHaveTextContent('50');
 
   fireEvent.click(sendControl);
   expect(sendSpy).toHaveBeenCalledTimes(1);
diff --git a/apps/example-app/app/examples/02-input-output.ts b/apps/example-app/src/app/examples/02-input-output.ts
similarity index 100%
rename from apps/example-app/app/examples/02-input-output.ts
rename to apps/example-app/src/app/examples/02-input-output.ts
diff --git a/apps/example-app/app/examples/03-forms.spec.ts b/apps/example-app/src/app/examples/03-forms.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/03-forms.spec.ts
rename to apps/example-app/src/app/examples/03-forms.spec.ts
diff --git a/apps/example-app/app/examples/03-forms.ts b/apps/example-app/src/app/examples/03-forms.ts
similarity index 100%
rename from apps/example-app/app/examples/03-forms.ts
rename to apps/example-app/src/app/examples/03-forms.ts
diff --git a/apps/example-app/app/examples/04-forms-with-material.spec.ts b/apps/example-app/src/app/examples/04-forms-with-material.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/04-forms-with-material.spec.ts
rename to apps/example-app/src/app/examples/04-forms-with-material.spec.ts
diff --git a/apps/example-app/app/examples/04-forms-with-material.ts b/apps/example-app/src/app/examples/04-forms-with-material.ts
similarity index 100%
rename from apps/example-app/app/examples/04-forms-with-material.ts
rename to apps/example-app/src/app/examples/04-forms-with-material.ts
diff --git a/apps/example-app/app/examples/05-component-provider.spec.ts b/apps/example-app/src/app/examples/05-component-provider.spec.ts
similarity index 89%
rename from apps/example-app/app/examples/05-component-provider.spec.ts
rename to apps/example-app/src/app/examples/05-component-provider.spec.ts
index 861eae76..79811245 100644
--- a/apps/example-app/app/examples/05-component-provider.spec.ts
+++ b/apps/example-app/src/app/examples/05-component-provider.spec.ts
@@ -18,14 +18,14 @@ test('renders the current value and can increment and decrement', async () => {
   const decrementControl = screen.getByRole('button', { name: /decrement/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('0');
+  expect(valueControl).toHaveTextContent('0');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('2');
+  expect(valueControl).toHaveTextContent('2');
 
   fireEvent.click(decrementControl);
-  expect(valueControl.textContent).toBe('1');
+  expect(valueControl).toHaveTextContent('1');
 });
 
 test('renders the current value and can increment and decrement with a mocked jest-utils service', async () => {
@@ -48,14 +48,14 @@ test('renders the current value and can increment and decrement with a mocked je
   const decrementControl = screen.getByRole('button', { name: /decrement/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('50');
+  expect(valueControl).toHaveTextContent('50');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('70');
+  expect(valueControl).toHaveTextContent('70');
 
   fireEvent.click(decrementControl);
-  expect(valueControl.textContent).toBe('60');
+  expect(valueControl).toHaveTextContent('60');
 });
 
 test('renders the current value and can increment and decrement with provideMocked from jest-utils', async () => {
diff --git a/apps/example-app/app/examples/05-component-provider.ts b/apps/example-app/src/app/examples/05-component-provider.ts
similarity index 100%
rename from apps/example-app/app/examples/05-component-provider.ts
rename to apps/example-app/src/app/examples/05-component-provider.ts
diff --git a/apps/example-app/app/examples/06-with-ngrx-store.spec.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
similarity index 84%
rename from apps/example-app/app/examples/06-with-ngrx-store.spec.ts
rename to apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
index d8a80d87..b8a289bb 100644
--- a/apps/example-app/app/examples/06-with-ngrx-store.spec.ts
+++ b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
@@ -21,12 +21,12 @@ test('works with ngrx store', async () => {
   const decrementControl = screen.getByRole('button', { name: /decrement/i });
   const valueControl = screen.getByTestId('value');
 
-  expect(valueControl.textContent).toBe('0');
+  expect(valueControl).toHaveTextContent('0');
 
   fireEvent.click(incrementControl);
   fireEvent.click(incrementControl);
-  expect(valueControl.textContent).toBe('20');
+  expect(valueControl).toHaveTextContent('20');
 
   fireEvent.click(decrementControl);
-  expect(valueControl.textContent).toBe('10');
+  expect(valueControl).toHaveTextContent('10');
 });
diff --git a/apps/example-app/app/examples/06-with-ngrx-store.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.ts
similarity index 100%
rename from apps/example-app/app/examples/06-with-ngrx-store.ts
rename to apps/example-app/src/app/examples/06-with-ngrx-store.ts
diff --git a/apps/example-app/app/examples/07-with-ngrx-mock-store.spec.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/07-with-ngrx-mock-store.spec.ts
rename to apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts
diff --git a/apps/example-app/app/examples/07-with-ngrx-mock-store.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts
similarity index 100%
rename from apps/example-app/app/examples/07-with-ngrx-mock-store.ts
rename to apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts
diff --git a/apps/example-app/app/examples/08-directive.spec.ts b/apps/example-app/src/app/examples/08-directive.spec.ts
similarity index 85%
rename from apps/example-app/app/examples/08-directive.spec.ts
rename to apps/example-app/src/app/examples/08-directive.spec.ts
index 1b8f234c..5df9413a 100644
--- a/apps/example-app/app/examples/08-directive.spec.ts
+++ b/apps/example-app/src/app/examples/08-directive.spec.ts
@@ -3,8 +3,8 @@ import { render, screen, fireEvent } from '@testing-library/angular';
 import { SpoilerDirective } from './08-directive';
 
 test('it is possible to test directives', async () => {
-  await render(SpoilerDirective, {
-    template: `<div appSpoiler data-testid="dir"></div>`,
+  await render('<div appSpoiler data-testid="dir"></div>', {
+    declarations: [SpoilerDirective],
   });
 
   const directive = screen.getByTestId('dir');
@@ -25,8 +25,8 @@ test('it is possible to test directives with props', async () => {
   const hidden = 'SPOILER ALERT';
   const visible = 'There is nothing to see here ...';
 
-  await render(SpoilerDirective, {
-    template: `<div appSpoiler [hidden]="hidden" [visible]="visible"></div>`,
+  await render('<div appSpoiler [hidden]="hidden" [visible]="visible"></div>', {
+    declarations: [SpoilerDirective],
     componentProperties: {
       hidden,
       visible,
@@ -49,8 +49,8 @@ test('it is possible to test directives with props in template', async () => {
   const hidden = 'SPOILER ALERT';
   const visible = 'There is nothing to see here ...';
 
-  await render(SpoilerDirective, {
-    template: `<div appSpoiler hidden="${hidden}" visible="${visible}"></div>`,
+  await render(`<div appSpoiler hidden="${hidden}" visible="${visible}"></div>`, {
+    declarations: [SpoilerDirective],
   });
 
   expect(screen.queryByText(visible)).not.toBeInTheDocument();
diff --git a/apps/example-app/app/examples/08-directive.ts b/apps/example-app/src/app/examples/08-directive.ts
similarity index 100%
rename from apps/example-app/app/examples/08-directive.ts
rename to apps/example-app/src/app/examples/08-directive.ts
diff --git a/apps/example-app/app/examples/09-router.spec.ts b/apps/example-app/src/app/examples/09-router.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/09-router.spec.ts
rename to apps/example-app/src/app/examples/09-router.spec.ts
diff --git a/apps/example-app/app/examples/09-router.ts b/apps/example-app/src/app/examples/09-router.ts
similarity index 91%
rename from apps/example-app/app/examples/09-router.ts
rename to apps/example-app/src/app/examples/09-router.ts
index e1ab5afb..035124c8 100644
--- a/apps/example-app/app/examples/09-router.ts
+++ b/apps/example-app/src/app/examples/09-router.ts
@@ -1,4 +1,4 @@
-import { OnInit, Component } from '@angular/core';
+import { Component } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { map } from 'rxjs/operators';
 
@@ -35,6 +35,6 @@ export class DetailComponent {
 
 @Component({
   selector: 'app-detail-hidden',
-  template: ` You found the treasure! `,
+  template: ' You found the treasure! ',
 })
 export class HiddenDetailComponent {}
diff --git a/apps/example-app/app/examples/10-inject-token-dependency.spec.ts b/apps/example-app/src/app/examples/10-inject-token-dependency.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/10-inject-token-dependency.spec.ts
rename to apps/example-app/src/app/examples/10-inject-token-dependency.spec.ts
diff --git a/apps/example-app/app/examples/10-inject-token-dependency.ts b/apps/example-app/src/app/examples/10-inject-token-dependency.ts
similarity index 89%
rename from apps/example-app/app/examples/10-inject-token-dependency.ts
rename to apps/example-app/src/app/examples/10-inject-token-dependency.ts
index 61bf5b41..8cc843e5 100644
--- a/apps/example-app/app/examples/10-inject-token-dependency.ts
+++ b/apps/example-app/src/app/examples/10-inject-token-dependency.ts
@@ -4,7 +4,7 @@ export const DATA = new InjectionToken<{ text: string }>('Components Data');
 
 @Component({
   selector: 'app-fixture',
-  template: ` {{ data.text }} `,
+  template: ' {{ data.text }} ',
 })
 export class DataInjectedComponent {
   constructor(@Inject(DATA) public data: { text: string }) {}
diff --git a/apps/example-app/app/examples/11-ng-content.spec.ts b/apps/example-app/src/app/examples/11-ng-content.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/11-ng-content.spec.ts
rename to apps/example-app/src/app/examples/11-ng-content.spec.ts
diff --git a/apps/example-app/app/examples/11-ng-content.ts b/apps/example-app/src/app/examples/11-ng-content.ts
similarity index 100%
rename from apps/example-app/app/examples/11-ng-content.ts
rename to apps/example-app/src/app/examples/11-ng-content.ts
diff --git a/apps/example-app/app/examples/12-service-component.spec.ts b/apps/example-app/src/app/examples/12-service-component.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/12-service-component.spec.ts
rename to apps/example-app/src/app/examples/12-service-component.spec.ts
diff --git a/apps/example-app/app/examples/12-service-component.ts b/apps/example-app/src/app/examples/12-service-component.ts
similarity index 100%
rename from apps/example-app/app/examples/12-service-component.ts
rename to apps/example-app/src/app/examples/12-service-component.ts
diff --git a/apps/example-app/app/examples/13-scrolling.component.spec.ts b/apps/example-app/src/app/examples/13-scrolling.component.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/13-scrolling.component.spec.ts
rename to apps/example-app/src/app/examples/13-scrolling.component.spec.ts
diff --git a/apps/example-app/app/examples/13-scrolling.component.ts b/apps/example-app/src/app/examples/13-scrolling.component.ts
similarity index 100%
rename from apps/example-app/app/examples/13-scrolling.component.ts
rename to apps/example-app/src/app/examples/13-scrolling.component.ts
diff --git a/apps/example-app/app/examples/14-async-component.spec.ts b/apps/example-app/src/app/examples/14-async-component.spec.ts
similarity index 100%
rename from apps/example-app/app/examples/14-async-component.spec.ts
rename to apps/example-app/src/app/examples/14-async-component.spec.ts
diff --git a/apps/example-app/app/examples/14-async-component.ts b/apps/example-app/src/app/examples/14-async-component.ts
similarity index 87%
rename from apps/example-app/app/examples/14-async-component.ts
rename to apps/example-app/src/app/examples/14-async-component.ts
index fbfd45ff..f8521539 100644
--- a/apps/example-app/app/examples/14-async-component.ts
+++ b/apps/example-app/src/app/examples/14-async-component.ts
@@ -1,4 +1,4 @@
-import { ApplicationInitStatus, Component, OnDestroy } from '@angular/core';
+import { Component, OnDestroy } from '@angular/core';
 import { Subject } from 'rxjs';
 import { delay, filter, mapTo } from 'rxjs/operators';
 
diff --git a/apps/example-app/app/examples/15-dialog.component.spec.ts b/apps/example-app/src/app/examples/15-dialog.component.spec.ts
similarity index 97%
rename from apps/example-app/app/examples/15-dialog.component.spec.ts
rename to apps/example-app/src/app/examples/15-dialog.component.spec.ts
index f5849abc..bcb41875 100644
--- a/apps/example-app/app/examples/15-dialog.component.spec.ts
+++ b/apps/example-app/src/app/examples/15-dialog.component.spec.ts
@@ -54,6 +54,7 @@ test('closes the dialog via the backdrop', async () => {
   await screen.findByRole('dialog');
   await screen.findByRole('heading', { name: /dialog title/i });
 
+  // eslint-disable-next-line testing-library/no-node-access
   fireEvent.click(document.querySelector('.cdk-overlay-backdrop'));
 
   await waitForElementToBeRemoved(() => screen.getByRole('dialog'));
diff --git a/apps/example-app/app/examples/15-dialog.component.ts b/apps/example-app/src/app/examples/15-dialog.component.ts
similarity index 83%
rename from apps/example-app/app/examples/15-dialog.component.ts
rename to apps/example-app/src/app/examples/15-dialog.component.ts
index ba7eb0da..af5d8d89 100644
--- a/apps/example-app/app/examples/15-dialog.component.ts
+++ b/apps/example-app/src/app/examples/15-dialog.component.ts
@@ -2,8 +2,8 @@ import { Component, NgModule } from '@angular/core';
 import { MatDialog, MatDialogRef } from '@angular/material/dialog';
 
 @Component({
-  selector: 'dialog-overview-example',
-  template: `<button (click)="openDialog()">Open dialog</button>`,
+  selector: 'app-dialog-overview-example',
+  template: '<button (click)="openDialog()">Open dialog</button>',
 })
 export class DialogComponent {
   constructor(public dialog: MatDialog) {}
@@ -14,7 +14,7 @@ export class DialogComponent {
 }
 
 @Component({
-  selector: 'dialog-overview-example-dialog',
+  selector: 'app-dialog-overview-example-dialog',
   template: `
     <h1 mat-dialog-title>Dialog Title</h1>
     <div mat-dialog-content>Dialog content</div>
diff --git a/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
new file mode 100644
index 00000000..28d736c6
--- /dev/null
+++ b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
@@ -0,0 +1,25 @@
+import { render, screen } from '@testing-library/angular';
+import { InputGetterSetter } from './16-input-getter-setter';
+
+test('should run logic in the input setter and getter', async () => {
+  await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
+  const valueControl = screen.getByTestId('value');
+  const getterValueControl = screen.getByTestId('value-getter');
+
+  expect(valueControl).toHaveTextContent('I am value from setter Angular');
+  expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
+});
+
+test('should run logic in the input setter and getter while re-rendering', async () => {
+  const { rerender } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
+  const valueControl = screen.getByTestId('value');
+  const getterValueControl = screen.getByTestId('value-getter');
+
+  expect(valueControl).toHaveTextContent('I am value from setter Angular');
+  expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
+
+  await rerender({ value: 'React' });
+
+  expect(valueControl).toHaveTextContent('I am value from setter React');
+  expect(getterValueControl).toHaveTextContent('I am value from getter React');
+});
diff --git a/apps/example-app/app/examples/16-input-getter-setter.ts b/apps/example-app/src/app/examples/16-input-getter-setter.ts
similarity index 88%
rename from apps/example-app/app/examples/16-input-getter-setter.ts
rename to apps/example-app/src/app/examples/16-input-getter-setter.ts
index d79f4fb9..11f8c949 100644
--- a/apps/example-app/app/examples/16-input-getter-setter.ts
+++ b/apps/example-app/src/app/examples/16-input-getter-setter.ts
@@ -7,6 +7,7 @@ import { Component, Input } from '@angular/core';
     <span data-testid="value-getter">{{ value }}</span>
   `,
 })
+// eslint-disable-next-line @angular-eslint/component-class-suffix
 export class InputGetterSetter {
   @Input() set value(value: string) {
     this.originalValue = value;
diff --git a/apps/example-app/app/examples/README.md b/apps/example-app/src/app/examples/README.md
similarity index 100%
rename from apps/example-app/app/examples/README.md
rename to apps/example-app/src/app/examples/README.md
diff --git a/apps/example-app/app/issues/issue-106.spec.ts b/apps/example-app/src/app/issues/issue-106.spec.ts
similarity index 82%
rename from apps/example-app/app/issues/issue-106.spec.ts
rename to apps/example-app/src/app/issues/issue-106.spec.ts
index 54dd1cb2..52bc81e1 100644
--- a/apps/example-app/app/issues/issue-106.spec.ts
+++ b/apps/example-app/src/app/issues/issue-106.spec.ts
@@ -20,14 +20,14 @@ it('https://github.com/testing-library/angular-testing-library/issues/106', asyn
   const toggle = screen.getByTestId('toggle');
   const hiddenText = screen.queryByTestId('getme');
 
-  expect(hiddenText).toBeNull();
+  expect(hiddenText).not.toBeInTheDocument();
   fireEvent.click(toggle);
 
   // fails
   // await waitFor(() => expect(hiddenText).not.toBeNull());
 
   // succeeds
-  await waitFor(() => expect(screen.queryByTestId('getme')).not.toBeNull());
+  await waitFor(() => expect(screen.queryByTestId('getme')).toBeInTheDocument());
 });
 
 it('better https://github.com/testing-library/angular-testing-library/issues/106', async () => {
@@ -35,8 +35,8 @@ it('better https://github.com/testing-library/angular-testing-library/issues/106
   const toggle = screen.getByTestId('toggle');
   const hiddenText = screen.queryByTestId('getme');
 
-  expect(hiddenText).toBeNull();
+  expect(hiddenText).not.toBeInTheDocument();
   fireEvent.click(toggle);
 
-  screen.getByTestId('getme');
+  expect(screen.getByTestId('getme')).toBeInTheDocument();
 });
diff --git a/apps/example-app/app/material.module.ts b/apps/example-app/src/app/material.module.ts
similarity index 100%
rename from apps/example-app/app/material.module.ts
rename to apps/example-app/src/app/material.module.ts
diff --git a/apps/example-app/assets/.gitkeep b/apps/example-app/src/assets/.gitkeep
similarity index 100%
rename from apps/example-app/assets/.gitkeep
rename to apps/example-app/src/assets/.gitkeep
diff --git a/apps/example-app/environments/environment.prod.ts b/apps/example-app/src/environments/environment.prod.ts
similarity index 100%
rename from apps/example-app/environments/environment.prod.ts
rename to apps/example-app/src/environments/environment.prod.ts
diff --git a/apps/example-app/environments/environment.ts b/apps/example-app/src/environments/environment.ts
similarity index 100%
rename from apps/example-app/environments/environment.ts
rename to apps/example-app/src/environments/environment.ts
diff --git a/apps/example-app/favicon.ico b/apps/example-app/src/favicon.ico
similarity index 100%
rename from apps/example-app/favicon.ico
rename to apps/example-app/src/favicon.ico
diff --git a/apps/example-app/index.html b/apps/example-app/src/index.html
similarity index 100%
rename from apps/example-app/index.html
rename to apps/example-app/src/index.html
diff --git a/apps/example-app/main.ts b/apps/example-app/src/main.ts
similarity index 100%
rename from apps/example-app/main.ts
rename to apps/example-app/src/main.ts
diff --git a/apps/example-app/polyfills.ts b/apps/example-app/src/polyfills.ts
similarity index 90%
rename from apps/example-app/polyfills.ts
rename to apps/example-app/src/polyfills.ts
index 5ead8153..1348d74b 100644
--- a/apps/example-app/polyfills.ts
+++ b/apps/example-app/src/polyfills.ts
@@ -14,7 +14,7 @@
  * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
  */
 
-/***************************************************************************************************
+/** *************************************************************************************************
  * BROWSER POLYFILLS
  */
 
@@ -65,11 +65,11 @@
  */
 // (window as any).__Zone_enable_cross_context_check = true;
 
-/***************************************************************************************************
+/** *************************************************************************************************
  * Zone JS is required by default for Angular itself.
  */
 import 'zone.js/dist/zone'; // Included with Angular CLI.
 
-/***************************************************************************************************
+/** *************************************************************************************************
  * APPLICATION IMPORTS
  */
diff --git a/apps/example-app/styles.css b/apps/example-app/src/styles.css
similarity index 100%
rename from apps/example-app/styles.css
rename to apps/example-app/src/styles.css
diff --git a/apps/example-app/test-setup.ts b/apps/example-app/src/test-setup.ts
similarity index 83%
rename from apps/example-app/test-setup.ts
rename to apps/example-app/src/test-setup.ts
index 13a4e108..8301387c 100644
--- a/apps/example-app/test-setup.ts
+++ b/apps/example-app/src/test-setup.ts
@@ -1,4 +1,4 @@
-import 'jest-preset-angular';
+import 'jest-preset-angular/setup-jest';
 import '@testing-library/jest-dom';
 import { configure } from '@testing-library/angular';
 import { ReactiveFormsModule } from '@angular/forms';
diff --git a/apps/example-app/tsconfig.app.json b/apps/example-app/tsconfig.app.json
new file mode 100644
index 00000000..629fd434
--- /dev/null
+++ b/apps/example-app/tsconfig.app.json
@@ -0,0 +1,9 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "../../dist/out-tsc",
+    "types": [],
+    "allowJs": true
+  },
+  "files": ["src/main.ts", "src/polyfills.ts"]
+}
diff --git a/apps/example-app/tsconfig.editor.json b/apps/example-app/tsconfig.editor.json
new file mode 100644
index 00000000..20c4afdb
--- /dev/null
+++ b/apps/example-app/tsconfig.editor.json
@@ -0,0 +1,7 @@
+{
+  "extends": "./tsconfig.json",
+  "include": ["**/*.ts"],
+  "compilerOptions": {
+    "types": ["jest", "node"]
+  }
+}
diff --git a/apps/example-app/tsconfig.json b/apps/example-app/tsconfig.json
index 91857b27..de50e310 100644
--- a/apps/example-app/tsconfig.json
+++ b/apps/example-app/tsconfig.json
@@ -1,9 +1,22 @@
 {
   "extends": "../../tsconfig.json",
-  "compilerOptions": {
-    "outDir": "../out-tsc/app",
-    "types": [],
-    "allowJs": true
+  "files": [],
+  "include": [],
+  "compilerOptions": {},
+  "angularCompilerOptions": {
+    "strictInjectionParameters": true,
+    "strictInputAccessModifiers": true,
+    "strictTemplates": true
   },
-  "files": ["main.ts", "polyfills.ts"]
+  "references": [
+    {
+      "path": "./tsconfig.app.json"
+    },
+    {
+      "path": "./tsconfig.spec.json"
+    },
+    {
+      "path": "./tsconfig.editor.json"
+    }
+  ]
 }
diff --git a/apps/example-app/tsconfig.spec.json b/apps/example-app/tsconfig.spec.json
index ba3de654..afe056ed 100644
--- a/apps/example-app/tsconfig.spec.json
+++ b/apps/example-app/tsconfig.spec.json
@@ -1,9 +1,10 @@
 {
-  "extends": "../../tsconfig.json",
+  "extends": "./tsconfig.json",
   "compilerOptions": {
+    "outDir": "../../dist/out-tsc",
     "module": "commonjs",
-    "types": ["node", "jest"]
+    "types": ["jest", "node", "@testing-library/jest-dom"]
   },
-  "files": ["test-setup.ts"],
+  "files": ["src/test-setup.ts"],
   "include": ["**/*.spec.ts", "**/*.d.ts"]
 }
diff --git a/apps/example-app/tslint.json b/apps/example-app/tslint.json
deleted file mode 100644
index 8006e74e..00000000
--- a/apps/example-app/tslint.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "../../tslint.json",
-  "rules": {
-    "directive-selector": [true, "attribute", "app", "camelCase"],
-    "component-selector": [true, "element", "app", "kebab-case"]
-  }
-}
diff --git a/jest.config.js b/jest.config.js
index 17d489e2..b52842c3 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,3 +1,3 @@
 module.exports = {
-  projects: ['<rootDir>/', '<rootDir>/projects/testing-library', '<rootDir>/projects/jest-utils'],
+  projects: ['<rootDir>/apps/example-app', '<rootDir>/projects/testing-library', '<rootDir>/projects/jest-utils'],
 };
diff --git a/jest.preset.js b/jest.preset.js
index b5989195..21c2ab11 100644
--- a/jest.preset.js
+++ b/jest.preset.js
@@ -8,11 +8,10 @@ module.exports = {
   resolver: '@nrwl/jest/plugins/resolver',
   moduleFileExtensions: ['ts', 'js', 'html'],
   coverageReporters: ['html'],
-  setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
   snapshotSerializers: [
-    'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
-    'jest-preset-angular/build/AngularSnapshotSerializer.js',
-    'jest-preset-angular/build/HTMLCommentSerializer.js',
+    'jest-preset-angular/build/serializers/no-ng-attributes',
+    'jest-preset-angular/build/serializers/ng-snapshot',
+    'jest-preset-angular/build/serializers/html-comment',
   ],
   globals: {
     'ts-jest': {
diff --git a/migrations.json b/migrations.json
new file mode 100644
index 00000000..1b29890b
--- /dev/null
+++ b/migrations.json
@@ -0,0 +1,89 @@
+{
+  "migrations": [
+    {
+      "version": "11.0.0-beta.3",
+      "description": "Update the decoration script when using Angular CLI",
+      "factory": "./src/migrations/update-11-0-0/update-decorate-angular-cli",
+      "package": "@nrwl/workspace",
+      "name": "update-decorate-angular-cli"
+    },
+    {
+      "version": "11.0.0-beta.3",
+      "description": "Update the @types/node package",
+      "factory": "./src/migrations/update-11-0-0/update-node-types",
+      "package": "@nrwl/workspace",
+      "name": "update-node-types"
+    },
+    {
+      "version": "11.0.0-beta.3",
+      "description": "Rename tools/schematics into tools/generators",
+      "factory": "./src/migrations/update-11-0-0/rename-workspace-schematics",
+      "package": "@nrwl/workspace",
+      "name": "rename-workspace-schematics"
+    },
+    {
+      "version": "11.0.0-beta.15",
+      "description": "Adds `outputs` based on builders",
+      "factory": "./src/migrations/update-11-0-0/add-outputs-in-workspace",
+      "package": "@nrwl/workspace",
+      "name": "add-outputs-in-workspace"
+    },
+    {
+      "version": "11.0.0",
+      "description": "Check that the right update command is used",
+      "factory": "./src/migrations/update-11-0-0/update-command-check",
+      "package": "@nrwl/workspace",
+      "name": "update-command-check"
+    },
+    {
+      "version": "11.0.2",
+      "description": "Rename the workspace-schematic script into workspace-generator script",
+      "factory": "./src/migrations/update-11-0-0/rename-workspace-schematic-script",
+      "package": "@nrwl/workspace",
+      "name": "rename-workspace-schematic-script"
+    },
+    {
+      "version": "10.5.0-beta.0",
+      "description": "Update eslint config and builder to extend from new Nx Angular presets and lint templates",
+      "factory": "./src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint",
+      "package": "@nrwl/angular",
+      "name": "add-template-support-and-presets-to-eslint"
+    },
+    {
+      "version": "11.0.0-beta.13",
+      "description": "Update builder configurations and dependencies",
+      "factory": "./src/migrations/update-11-0-0/update-builders-config",
+      "package": "@nrwl/angular",
+      "name": "update-11-0-0"
+    },
+    {
+      "version": "12.0.0-beta.0",
+      "description": "adjusts the ngcc postinstall command to just leave 'ngcc' in there. This fixes Ivy in Jest tests and Storybooks",
+      "factory": "./src/migrations/update-12-0-0/update-ngcc-postinstall",
+      "package": "@nrwl/angular",
+      "name": "update-ngcc-postinstall"
+    },
+    {
+      "cli": "nx",
+      "version": "11.5.0-beta.0",
+      "description": "Update project .eslintrc.json files to always use project level tsconfigs",
+      "factory": "./src/migrations/update-11-5-0/always-use-project-level-tsconfigs-with-eslint",
+      "package": "@nrwl/linter",
+      "name": "always-use-project-level-tsconfigs-with-eslint"
+    },
+    {
+      "version": "11.0.0-beta.4",
+      "description": "Rename ng-update into nx-migrate",
+      "factory": "./src/migrations/update-11-0-0/rename-ng-update-into-nx-migrate",
+      "package": "@nrwl/nx-plugin",
+      "name": "rename-ng-update-into-nx-migrate"
+    },
+    {
+      "version": "11.0.17",
+      "description": "Update schema versions for executors and generators",
+      "factory": "./src/migrations/update-11-0-0/update-schema-version-for-executors-and-generators",
+      "package": "@nrwl/nx-plugin",
+      "name": "update-schema-version-for-executors-and-generators"
+    }
+  ]
+}
diff --git a/nx.json b/nx.json
index 0473fa55..c99139c8 100644
--- a/nx.json
+++ b/nx.json
@@ -1,23 +1,24 @@
 {
-  "npmScope": "testing-library",
   "implicitDependencies": {
     "angular.json": "*",
-    "package.json": "*",
-    "tsconfig.json": "*",
-    "tslint.json": "*",
+    "package.json": {
+      "dependencies": "*",
+      "devDependencies": "*"
+    },
+    "tsconfig.base.json": "*",
+    ".eslintrc.json": "*",
     "nx.json": "*"
   },
+  "affected": {
+    "defaultBase": "master"
+  },
+  "npmScope": "testing-library",
   "tasksRunnerOptions": {
     "default": {
       "runner": "@nrwl/nx-cloud",
       "options": {
         "accessToken": "M2Q4YjlkNjMtMzY1NC00ZjkwLTk1ZjgtZjg5Y2VkMzFjM2FifHJlYWQtd3JpdGU=",
-        "cacheableOperations": [
-          "build",
-          "test",
-          "lint",
-          "e2e"
-        ],
+        "cacheableOperations": ["build", "test", "lint", "e2e"],
         "canTrackAnalytics": false,
         "showUsageWarnings": true
       }
diff --git a/package.json b/package.json
index 5dd16630..0490d1c6 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
   "version": "0.0.0-semantically-released",
   "scripts": {
     "ng": "ng",
+    "nx": "nx",
     "postinstall": "ngcc",
     "start": "ng serve",
     "build": "nx run-many --target=build --projects=testing-library,jest-utils",
@@ -17,57 +18,69 @@
     "affected:lint": "nx affected:lint",
     "affected:dep-graph": "nx affected:dep-graph",
     "affected": "nx affected",
+    "format": "nx format:write",
+    "format:write": "nx format:write",
+    "format:check": "nx format:check",
     "precommit": "lint-staged",
     "semantic-release": "semantic-release"
   },
   "dependencies": {
-    "@angular/animations": "^11.0.0",
-    "@angular/cdk": "^11.0.0",
-    "@angular/common": "^11.0.0",
-    "@angular/compiler": "^11.0.0",
-    "@angular/core": "^11.0.0",
-    "@angular/forms": "^11.0.0",
-    "@angular/material": "^11.0.0",
-    "@angular/platform-browser": "^11.0.0",
-    "@angular/platform-browser-dynamic": "^11.0.0",
-    "@angular/router": "^11.0.0",
-    "@ngrx/store": "^10.0.1",
-    "@nrwl/angular": "^10.3.3",
-    "@nrwl/nx-cloud": "^10.0.0",
-    "@phenomnomnominal/tsquery": "^4.1.1",
+    "@angular/animations": "11.2.9",
+    "@angular/cdk": "11.2.9",
+    "@angular/common": "11.2.9",
+    "@angular/compiler": "11.2.9",
+    "@angular/core": "11.2.9",
+    "@angular/forms": "11.2.9",
+    "@angular/material": "11.2.9",
+    "@angular/platform-browser": "11.2.9",
+    "@angular/platform-browser-dynamic": "11.2.9",
+    "@angular/router": "11.2.9",
+    "@ngrx/store": "11.0.0",
+    "@nrwl/angular": "12.0.3",
+    "@nrwl/nx-cloud": "11.2.0",
     "@testing-library/dom": "7.29.4",
     "@testing-library/user-event": "^12.0.11",
     "core-js": "^3.6.5",
     "rxjs": "^6.5.5",
     "tslib": "^2.0.0",
-    "tslint": "~6.1.0",
-    "zone.js": "~0.10.3"
+    "zone.js": "~0.11.4"
   },
   "devDependencies": {
-    "@angular-devkit/build-angular": "~0.1100.0",
-    "@angular/cli": "~11.0.0",
-    "@angular/compiler-cli": "^11.0.0",
-    "@angular/language-service": "^11.0.0",
-    "@nrwl/cli": "10.3.3",
-    "@nrwl/jest": "^10.3.3",
-    "@nrwl/node": "^10.3.3",
-    "@nrwl/nx-plugin": "^10.3.3",
-    "@nrwl/workspace": "^10.3.3",
-    "@testing-library/jest-dom": "^5.11.0",
+    "@angular-devkit/build-angular": "0.1102.8",
+    "@angular-eslint/eslint-plugin": "~2.1.0",
+    "@angular-eslint/eslint-plugin-template": "~2.1.0",
+    "@angular-eslint/template-parser": "~2.1.0",
+    "@angular/cli": "11.2.8",
+    "@angular/compiler-cli": "11.2.9",
+    "@angular/language-service": "11.2.9",
+    "@nrwl/cli": "12.0.3",
+    "@nrwl/eslint-plugin-nx": "12.0.3",
+    "@nrwl/jest": "12.0.3",
+    "@nrwl/linter": "12.0.3",
+    "@nrwl/node": "12.0.3",
+    "@nrwl/nx-plugin": "12.0.3",
+    "@nrwl/workspace": "12.0.3",
+    "@testing-library/jest-dom": "^5.11.10",
     "@types/jest": "~26.0.3",
-    "@types/node": "^14.0.14",
-    "codelyzer": "^5.2.2",
+    "@types/node": "14.14.37",
+    "@typescript-eslint/eslint-plugin": "4.22.0",
+    "@typescript-eslint/parser": "4.22.0",
     "cpy-cli": "^3.1.1",
+    "eslint": "7.24.0",
+    "eslint-config-prettier": "8.2.0",
+    "eslint-plugin-import": "latest",
+    "eslint-plugin-jest-dom": "3.8.0",
+    "eslint-plugin-testing-library": "^4.0.1",
     "husky": "^4.2.5",
     "jest": "^26.1.0",
-    "jest-preset-angular": "8.3.1",
+    "jest-preset-angular": "8.4.0",
     "lint-staged": "^10.2.11",
-    "ng-packagr": "^11.0.1",
-    "prettier": "^2.0.5",
+    "ng-packagr": "11.2.4",
+    "prettier": "2.2.1",
     "rimraf": "^3.0.2",
     "semantic-release": "^17.1.1",
-    "ts-jest": "26.4.0",
-    "ts-node": "~8.10.2",
-    "typescript": "~4.0.5"
+    "ts-jest": "26.5.4",
+    "ts-node": "9.1.1",
+    "typescript": "4.1.4"
   }
 }
diff --git a/projects/jest-utils/.eslintrc.json b/projects/jest-utils/.eslintrc.json
new file mode 100644
index 00000000..4687290e
--- /dev/null
+++ b/projects/jest-utils/.eslintrc.json
@@ -0,0 +1,36 @@
+{
+  "extends": "../../.eslintrc.json",
+  "ignorePatterns": ["!**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts"],
+      "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
+      "parserOptions": {
+        "project": ["projects/jest-utils/tsconfig.*?.json"]
+      },
+      "rules": {
+        "@angular-eslint/directive-selector": [
+          "error",
+          {
+            "type": "attribute",
+            "prefix": "lib",
+            "style": "camelCase"
+          }
+        ],
+        "@angular-eslint/component-selector": [
+          "error",
+          {
+            "type": "element",
+            "prefix": "lib",
+            "style": "kebab-case"
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.html"],
+      "extends": ["plugin:@nrwl/nx/angular-template"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/projects/jest-utils/src/lib/create-mock.ts b/projects/jest-utils/src/lib/create-mock.ts
index 7d18f152..7b9c1ecd 100644
--- a/projects/jest-utils/src/lib/create-mock.ts
+++ b/projects/jest-utils/src/lib/create-mock.ts
@@ -29,10 +29,7 @@ export function createMock<T>(type: Type<T>): Mock<T> {
   return mock;
 }
 
-export function createMockWithValues<T, K extends keyof T>(
-  type: Type<T>,
-  values: Partial<Record<K, T[K]>>,
-): Mock<T> {
+export function createMockWithValues<T, K extends keyof T>(type: Type<T>, values: Partial<Record<K, T[K]>>): Mock<T> {
   const mock = createMock(type);
 
   Object.entries(values).forEach(([field, value]) => {
diff --git a/projects/jest-utils/test-setup.ts b/projects/jest-utils/test-setup.ts
index 9020de51..0da94a0a 100644
--- a/projects/jest-utils/test-setup.ts
+++ b/projects/jest-utils/test-setup.ts
@@ -1,2 +1,2 @@
-import 'jest-preset-angular';
+import 'jest-preset-angular/setup-jest';
 import '@testing-library/jest-dom';
diff --git a/projects/jest-utils/tsconfig.spec.json b/projects/jest-utils/tsconfig.spec.json
index ba3de654..091c5cf3 100644
--- a/projects/jest-utils/tsconfig.spec.json
+++ b/projects/jest-utils/tsconfig.spec.json
@@ -2,7 +2,7 @@
   "extends": "../../tsconfig.json",
   "compilerOptions": {
     "module": "commonjs",
-    "types": ["node", "jest"]
+    "types": ["node", "jest", "@testing-library/jest-dom"]
   },
   "files": ["test-setup.ts"],
   "include": ["**/*.spec.ts", "**/*.d.ts"]
diff --git a/projects/jest-utils/tslint.json b/projects/jest-utils/tslint.json
deleted file mode 100644
index 0946f209..00000000
--- a/projects/jest-utils/tslint.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "extends": "../../tslint.json"
-}
diff --git a/projects/testing-library/.eslintrc.json b/projects/testing-library/.eslintrc.json
new file mode 100644
index 00000000..f3960e87
--- /dev/null
+++ b/projects/testing-library/.eslintrc.json
@@ -0,0 +1,36 @@
+{
+  "extends": "../../.eslintrc.json",
+  "ignorePatterns": ["!**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts"],
+      "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
+      "parserOptions": {
+        "project": ["projects/testing-library/tsconfig.*?.json"]
+      },
+      "rules": {
+        "@angular-eslint/directive-selector": [
+          "error",
+          {
+            "type": "attribute",
+            "prefix": "lib",
+            "style": "camelCase"
+          }
+        ],
+        "@angular-eslint/component-selector": [
+          "error",
+          {
+            "type": "element",
+            "prefix": "lib",
+            "style": "kebab-case"
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.html"],
+      "extends": ["plugin:@nrwl/nx/angular-template"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/projects/testing-library/migrations/4_0_0/index.ts b/projects/testing-library/migrations/4_0_0/index.ts
deleted file mode 100644
index 1bd4aad4..00000000
--- a/projects/testing-library/migrations/4_0_0/index.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Rule } from '@angular-devkit/schematics';
-import { TslintFixTask } from '@angular-devkit/schematics/tasks';
-import * as path from 'path';
-
-function createRule(ruleName: string): TslintFixTask {
-  return new TslintFixTask(
-    {
-      rulesDirectory: path.join(__dirname, 'rules'),
-      rules: {
-        [ruleName]: [true],
-      },
-    },
-    {
-      includes: ['**/*.spec.ts', '**/*.test.ts'],
-      silent: false,
-    },
-  );
-}
-
-export default function (): Rule {
-  return (_, context) => {
-    const noCreateComponentRule = createRule('no-create-component');
-    const noComponentParametersRule = createRule('no-component-parameters');
-    const noComponentPropertyRule = createRule('no-component-property');
-
-    const noCreateComponentRuleId = context.addTask(noCreateComponentRule);
-    const noComponentParametersRuleId = context.addTask(noComponentParametersRule, [noCreateComponentRuleId]);
-    context.addTask(noComponentPropertyRule, [noComponentParametersRuleId]);
-  };
-}
diff --git a/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts b/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts
deleted file mode 100644
index 791b3c15..00000000
--- a/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import * as ts from 'typescript';
-import { Replacement, RuleFailure, Rules } from 'tslint';
-import { tsquery } from '@phenomnomnominal/tsquery';
-
-const IS_COMPONENT_PROPERTY_QUERY =
-  'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:first-child';
-const RENDER_OPTIONS_QUERY = 'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:last-child';
-const COMPONENT_PARAMETERS_PROPERTY_VALUE_QUERY = 'PropertyAssignment:has(Identifier[name="parameters"]) :last-child';
-
-const FAILURE_MESSAGE = 'Found `parameters` parameter, use `componentProperties` instead.';
-
-export class Rule extends Rules.AbstractRule {
-  public apply(ast: ts.SourceFile): Array<RuleFailure> {
-    return tsquery(ast, IS_COMPONENT_PROPERTY_QUERY)
-      .map((result) => {
-        const [parameterNode] = tsquery(result, COMPONENT_PARAMETERS_PROPERTY_VALUE_QUERY);
-        if (!parameterNode) {
-          return [];
-        }
-        const [renderOptionsNode] = tsquery(ast, RENDER_OPTIONS_QUERY);
-
-        const renderOptionsText = renderOptionsNode.getFullText();
-        const bracketIndex = renderOptionsText.indexOf('{');
-        const renderOptions =
-          renderOptionsText.substring(0, bracketIndex + 1) +
-          `componentProperties:${parameterNode.getFullText()},` +
-          renderOptionsText.substr(bracketIndex + 1);
-
-        const replacement = new Replacement(renderOptionsNode.getStart(), renderOptionsNode.getWidth(), renderOptions);
-        const start = renderOptionsNode.getStart();
-        const end = renderOptionsNode.getEnd();
-
-        const replacementOriginal = new Replacement(parameterNode.getStart(), parameterNode.getWidth(), '');
-        const startOriginal = renderOptionsNode.getStart();
-        const endOriginal = renderOptionsNode.getEnd();
-
-        return [
-          new RuleFailure(ast, startOriginal, endOriginal, FAILURE_MESSAGE, this.ruleName, replacementOriginal),
-          new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement),
-        ];
-      })
-      .reduce((rules, rule) => rules.concat(rule), []);
-  }
-}
diff --git a/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts b/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts
deleted file mode 100644
index 9c6d012c..00000000
--- a/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as ts from 'typescript';
-import { Replacement, RuleFailure, Rules } from 'tslint';
-import { tsquery } from '@phenomnomnominal/tsquery';
-
-const IS_COMPONENT_PROPERTY_QUERY =
-  'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:first-child';
-const COMPONENT_PROPERTY_VALUE_QUERY = 'PropertyAssignment:has(Identifier[name="component"]) :last-child';
-
-const FAILURE_MESSAGE = 'Found component propety syntax, signature looks different.';
-
-export class Rule extends Rules.AbstractRule {
-  public apply(ast: ts.SourceFile): Array<RuleFailure> {
-    return tsquery(ast, IS_COMPONENT_PROPERTY_QUERY).map((result) => {
-      const [valueNode] = tsquery(result, COMPONENT_PROPERTY_VALUE_QUERY);
-      const replacement = new Replacement(result.getStart(), result.getWidth(), (valueNode || result).getText());
-      const start = result.getStart();
-      const end = result.getEnd();
-
-      return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement);
-    });
-  }
-}
diff --git a/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts b/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts
deleted file mode 100644
index 5ed4dbc0..00000000
--- a/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as ts from 'typescript';
-import { Replacement, RuleFailure, Rules } from 'tslint';
-import { tsquery } from '@phenomnomnominal/tsquery';
-
-const CREATE_COMPONENT_IDENTIFIER = 'Identifier[name="createComponent"]';
-const CREATE_COMPONENT_IMPORT_QUERY = `ImportSpecifier > ${CREATE_COMPONENT_IDENTIFIER}`;
-const CREATE_COMPONENT_CALL_EXPRESSION_QUERY = `CallExpression > ${CREATE_COMPONENT_IDENTIFIER}`;
-
-const RENDER = 'render';
-
-const FAILURE_MESSAGE = 'Found `createComponent`, use `render` instead.';
-
-export class Rule extends Rules.AbstractRule {
-  public apply(ast: ts.SourceFile): Array<RuleFailure> {
-    const imports = this.getImports(ast);
-    const usages = this.getUsages(ast);
-
-    return [...imports, ...usages];
-  }
-
-  private getImports(ast: ts.SourceFile): Array<RuleFailure> {
-    return tsquery(ast, CREATE_COMPONENT_IMPORT_QUERY).map((result) => {
-      const replacement = new Replacement(result.getStart(), result.getWidth(), RENDER);
-      const start = result.getStart();
-      const end = result.getEnd();
-
-      return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement);
-    });
-  }
-
-  private getUsages(ast: ts.SourceFile): Array<RuleFailure> {
-    return tsquery(ast, CREATE_COMPONENT_CALL_EXPRESSION_QUERY).map((result) => {
-      const replacement = new Replacement(result.getStart(), result.getWidth(), RENDER);
-      const start = result.getStart();
-      const end = result.getEnd();
-
-      return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement);
-    });
-  }
-}
diff --git a/projects/testing-library/migrations/5_1_2/index.ts b/projects/testing-library/migrations/5_1_2/index.ts
deleted file mode 100644
index b35fd19c..00000000
--- a/projects/testing-library/migrations/5_1_2/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Rule, chain, Tree, SchematicContext } from '@angular-devkit/schematics';
-import { TslintFixTask } from '@angular-devkit/schematics/tasks';
-import * as path from 'path';
-import { stripIndents } from '@angular-devkit/core/src/utils/literals';
-
-function createRule(ruleName: string): TslintFixTask {
-  return new TslintFixTask(
-    {
-      rulesDirectory: path.join(__dirname, 'rules'),
-      rules: {
-        [ruleName]: [true],
-      },
-    },
-    {
-      includes: ['**/*.spec.ts', '**/*.test.ts'],
-      silent: false,
-    },
-  );
-}
-
-function displayInformation(tree, context: SchematicContext) {
-  context.logger.info(stripIndents`
-    @angular-extensions/testing-library has moved to @testing-library/angular.
-
-    Learn more about this change here: https://github.com/testing-library/dom-testing-library/issues/260
-  `);
-
-  return tree;
-}
-
-function updatePackageJson(host: Tree) {
-  if (host.exists('package.json')) {
-    // tslint:disable-next-line: no-non-null-assertion
-    const sourceText = host.read('package.json')!.toString('utf-8');
-    const json = JSON.parse(sourceText);
-
-    if (json['devDependencies'] && json['devDependencies']['@angular-extensions/testing-library']) {
-      json['devDependencies']['@testing-library/angular'] = '^6.0.0';
-      delete json['devDependencies']['@angular-extensions/testing-library'];
-      host.overwrite('package.json', JSON.stringify(json, null, 2));
-    }
-  }
-
-  return host;
-}
-
-export default function (): Rule {
-  return (host, context) => {
-    context.addTask(createRule('no-angular-extensions-import'));
-
-    return chain([displayInformation, updatePackageJson])(host, context);
-  };
-}
diff --git a/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts b/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts
deleted file mode 100644
index f8ab045f..00000000
--- a/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import * as ts from 'typescript';
-import { Replacement, RuleFailure, Rules } from 'tslint';
-import { tsquery } from '@phenomnomnominal/tsquery';
-
-const IMPORT_QUERY = `ImportDeclaration StringLiteral[value="@angular-extensions/testing-library"]`;
-
-const FAILURE_MESSAGE =
-  'Found the library `@angular-extensions/testing-library`, use `@testing-library/angular` instead.';
-
-export class Rule extends Rules.AbstractRule {
-  public apply(ast: ts.SourceFile): Array<RuleFailure> {
-    const imports = this.getImports(ast);
-    return imports;
-  }
-
-  private getImports(ast: ts.SourceFile): Array<RuleFailure> {
-    return tsquery(ast, IMPORT_QUERY).map((result) => {
-      // replace text between (single) quotes
-      const replacement = new Replacement(result.getStart() + 1, result.getWidth() - 2, '@testing-library/angular');
-      const start = result.getStart();
-      const end = result.getEnd();
-
-      return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement);
-    });
-  }
-}
diff --git a/projects/testing-library/migrations/migration.json b/projects/testing-library/migrations/migration.json
deleted file mode 100644
index 7a7cc7a4..00000000
--- a/projects/testing-library/migrations/migration.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
-  "schematics": {
-    "migration-4.0.0": {
-      "version": "4.0.0",
-      "description": "Align API to *-testing-libraries",
-      "factory": "./4_0_0"
-    },
-    "migration-5.1.2": {
-      "version": "5.1.2",
-      "description": "Migrate to @testing-library",
-      "factory": "./5_1_2"
-    }
-  }
-}
diff --git a/projects/testing-library/migrations/tsconfig.migrations.json b/projects/testing-library/migrations/tsconfig.migrations.json
deleted file mode 100644
index 794ddbb2..00000000
--- a/projects/testing-library/migrations/tsconfig.migrations.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "compilerOptions": {
-    "module": "commonjs",
-    "target": "es5",
-    "sourceMap": true,
-    "rootDir": "./",
-    "outDir": "../../../dist/@testing-library/angular/migrations",
-    "noLib": false,
-    "baseUrl": "./",
-    "experimentalDecorators": true,
-    "skipLibCheck": true,
-    "declaration": true,
-    "removeComments": true,
-    "lib": ["es6"]
-  },
-  "include": ["."]
-}
diff --git a/projects/testing-library/ng-package.json b/projects/testing-library/ng-package.json
index 48f090fa..146b130f 100644
--- a/projects/testing-library/ng-package.json
+++ b/projects/testing-library/ng-package.json
@@ -5,10 +5,5 @@
   "lib": {
     "entryFile": "index.ts"
   },
-  "whitelistedNonPeerDependencies": [
-    "@testing-library/dom",
-    "@testing-library/user-event",
-    "@phenomnomnominal/tsquery",
-    "tslint"
-  ]
+  "allowedNonPeerDependencies": ["@testing-library/dom"]
 }
diff --git a/projects/testing-library/package.json b/projects/testing-library/package.json
index 17ad15d4..7fb78fff 100644
--- a/projects/testing-library/package.json
+++ b/projects/testing-library/package.json
@@ -30,14 +30,9 @@
   },
   "dependencies": {
     "@testing-library/dom": "7.29.4",
-    "@phenomnomnominal/tsquery": "^4.1.1",
-    "tslib": "^2.0.0",
-    "tslint": "^5.16.0"
+    "tslib": "^2.0.0"
   },
   "publishConfig": {
     "access": "public"
-  },
-  "ng-update": {
-    "migrations": "./migrations/migration.json"
   }
 }
diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts
index 5d9b225b..b1984477 100644
--- a/projects/testing-library/src/lib/models.ts
+++ b/projects/testing-library/src/lib/models.ts
@@ -250,6 +250,10 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
   removeAngularAttributes?: boolean;
 }
 
+/**
+ * @deprecated Use `render(template, { declarations: [SomeDirective] })` instead.
+ */
+// eslint-disable-next-line @typescript-eslint/ban-types
 export interface RenderDirectiveOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries>
   extends RenderComponentOptions<Properties, Q> {
   /**
@@ -261,6 +265,8 @@ export interface RenderDirectiveOptions<WrapperType, Properties extends object =
    * const component = await render(SpoilerDirective, {
    *  template: `<div spoiler message='SPOILER'></div>`
    * })
+   *
+   * @deprecated Use `render(template, { declarations: [SomeDirective] })` instead.
    */
   template: string;
   /**
@@ -281,6 +287,27 @@ export interface RenderDirectiveOptions<WrapperType, Properties extends object =
   componentProperties?: Partial<WrapperType & Properties>;
 }
 
+// eslint-disable-next-line @typescript-eslint/ban-types
+export interface RenderTemplateOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries>
+  extends RenderComponentOptions<Properties, Q> {
+  /**
+   * @description
+   * An Angular component to wrap the component in.
+   * The template will be overridden with the `template` option.
+   *
+   * @default
+   * `WrapperComponent`, an empty component that strips the `ng-version` attribute
+   *
+   * @example
+   * const component = await render(SpoilerDirective, {
+   *  template: `<div spoiler message='SPOILER'></div>`
+   *  wrapper: CustomWrapperComponent
+   * })
+   */
+  wrapper?: Type<WrapperType>;
+  componentProperties?: Partial<WrapperType & Properties>;
+}
+
 export interface Config extends Pick<RenderComponentOptions<any>, 'excludeComponentDeclaration'> {
   /**
    * DOM Testing Library config
diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index 62c2c0c0..fe3a22ca 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -22,7 +22,7 @@ import {
   waitForOptions as dtlWaitForOptions,
   configure as dtlConfigure,
 } from '@testing-library/dom';
-import { RenderComponentOptions, RenderDirectiveOptions, RenderResult } from './models';
+import { RenderComponentOptions, RenderDirectiveOptions, RenderTemplateOptions, RenderResult } from './models';
 import { getConfig } from './config';
 
 const mountedFixtures = new Set<ComponentFixture<any>>();
@@ -32,14 +32,24 @@ export async function render<ComponentType>(
   component: Type<ComponentType>,
   renderOptions?: RenderComponentOptions<ComponentType>,
 ): Promise<RenderResult<ComponentType, ComponentType>>;
+/**
+ * @deprecated Use `render(template, { declarations: [DirectiveType] })` instead.
+ */
 export async function render<DirectiveType, WrapperType = WrapperComponent>(
   component: Type<DirectiveType>,
   renderOptions?: RenderDirectiveOptions<WrapperType>,
 ): Promise<RenderResult<WrapperType>>;
+export async function render<WrapperType = WrapperComponent>(
+  template: string,
+  renderOptions?: RenderTemplateOptions<WrapperType>,
+): Promise<RenderResult<WrapperType>>;
 
 export async function render<SutType, WrapperType = SutType>(
-  sut: Type<SutType>,
-  renderOptions: RenderComponentOptions<SutType> | RenderDirectiveOptions<WrapperType> = {},
+  sut: Type<SutType> | string,
+  renderOptions:
+    | RenderComponentOptions<SutType>
+    | RenderDirectiveOptions<WrapperType>
+    | RenderTemplateOptions<WrapperType> = {},
 ): Promise<RenderResult<SutType>> {
   const { dom: domConfig, ...globalConfig } = getConfig();
   const {
@@ -69,7 +79,12 @@ export async function render<SutType, WrapperType = SutType>(
   });
 
   TestBed.configureTestingModule({
-    declarations: addAutoDeclarations(sut, { declarations, excludeComponentDeclaration, template, wrapper }),
+    declarations: addAutoDeclarations(sut, {
+      declarations,
+      excludeComponentDeclaration,
+      template,
+      wrapper,
+    }),
     imports: addAutoImports({
       imports: imports.concat(defaultImports),
       routes,
@@ -176,7 +191,7 @@ export async function render<SutType, WrapperType = SutType>(
     detectChanges,
     navigate,
     rerender,
-    debugElement: fixture.debugElement.query(By.directive(sut)),
+    debugElement: typeof sut === 'string' ? fixture.debugElement : fixture.debugElement.query(By.directive(sut)),
     container: fixture.nativeElement,
     debug: (element = fixture.nativeElement, maxLength, options) =>
       Array.isArray(element)
@@ -193,14 +208,18 @@ async function createComponent<SutType>(component: Type<SutType>): Promise<Compo
 }
 
 async function createComponentFixture<SutType>(
-  component: Type<SutType>,
+  sut: Type<SutType> | string,
   { template, wrapper }: Pick<RenderDirectiveOptions<any>, 'template' | 'wrapper'>,
 ): Promise<ComponentFixture<SutType>> {
+  if (typeof sut === 'string') {
+    TestBed.overrideTemplate(wrapper, sut);
+    return createComponent(wrapper);
+  }
   if (template) {
     TestBed.overrideTemplate(wrapper, template);
     return createComponent(wrapper);
   }
-  return createComponent(component);
+  return createComponent(sut);
 }
 
 function setComponentProperties<SutType>(
@@ -248,7 +267,7 @@ function getChangesObj<SutType>(oldProps: Partial<SutType> | null, newProps: Par
 }
 
 function addAutoDeclarations<SutType>(
-  component: Type<SutType>,
+  sut: Type<SutType> | string,
   {
     declarations,
     excludeComponentDeclaration,
@@ -256,13 +275,13 @@ function addAutoDeclarations<SutType>(
     wrapper,
   }: Pick<RenderDirectiveOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>,
 ) {
-  const wrappers = () => {
-    return template ? [wrapper] : [];
-  };
+  if (typeof sut === 'string') {
+    return [...declarations, wrapper];
+  }
 
-  const components = () => {
-    return excludeComponentDeclaration ? [] : [component];
-  };
+  const wrappers = () => (template ? [wrapper] : []);
+
+  const components = () => (excludeComponentDeclaration ? [] : [sut]);
 
   return [...declarations, ...wrappers(), ...components()];
 }
@@ -274,9 +293,7 @@ function addAutoImports({ imports, routes }: Pick<RenderComponentOptions<any>, '
     return animationIsDefined ? [] : [NoopAnimationsModule];
   };
 
-  const routing = () => {
-    return routes ? [RouterTestingModule.withRoutes(routes)] : [];
-  };
+  const routing = () => (routes ? [RouterTestingModule.withRoutes(routes)] : []);
 
   return [...imports, ...animations(), ...routing()];
 }
@@ -341,6 +358,7 @@ if (typeof afterEach === 'function' && !process.env.ATL_SKIP_AUTO_CLEANUP) {
   });
 }
 
+// eslint-disable-next-line @angular-eslint/component-selector
 @Component({ selector: 'wrapper-component', template: '' })
 class WrapperComponent {}
 
diff --git a/projects/testing-library/test-setup.ts b/projects/testing-library/test-setup.ts
index 9020de51..0da94a0a 100644
--- a/projects/testing-library/test-setup.ts
+++ b/projects/testing-library/test-setup.ts
@@ -1,2 +1,2 @@
-import 'jest-preset-angular';
+import 'jest-preset-angular/setup-jest';
 import '@testing-library/jest-dom';
diff --git a/projects/testing-library/tests/migration/4_0_0.spec.ts b/projects/testing-library/tests/migration/4_0_0.spec.ts
deleted file mode 100644
index 8c82963b..00000000
--- a/projects/testing-library/tests/migration/4_0_0.spec.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { getSystemPath, normalize, virtualFs } from '@angular-devkit/core';
-import { TempScopedNodeJsSyncHost } from '@angular-devkit/core/node/testing';
-import { HostTree } from '@angular-devkit/schematics';
-import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
-
-describe('Migration to version 4.0.0', () => {
-  /* tslint:disable */
-  const fixtures = [
-    {
-      description: 'template syntax',
-      input: virtualFs.stringToFileBuffer(`
-        import { createComponent } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await createComponent<HomeComponent>('<home></home>', {
-            declarations: [HomeComponent],
-          });
-        }`),
-      expected: `
-        import { render } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await render<HomeComponent>('<home></home>', {
-            declarations: [HomeComponent],
-          });
-        }`,
-    },
-    {
-      description: 'component syntax',
-      input: virtualFs.stringToFileBuffer(`
-        import { createComponent } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await createComponent(
-            {
-              component: HomeComponent
-            },
-            {
-              declarations: [HomeComponent],
-            }
-          );
-        }`),
-      expected: `
-        import { render } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await render(
-            HomeComponent,
-            {
-              declarations: [HomeComponent],
-            }
-          );
-        }`,
-    },
-    {
-      description: 'component syntax with properties',
-      input: virtualFs.stringToFileBuffer(`
-        import { createComponent } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await createComponent(
-            {
-              component: HomeComponent,
-              parameters: {
-                value: 'foo',
-                count: 2
-              },
-            },
-            {
-              declarations: [HomeComponent],
-            }
-          );
-        }`),
-      expected: `
-        import { render } from '@testing-library/angular';
-        import { HomeComponent } from './home.component';
-
-        async function setup() {
-          await render(
-            HomeComponent,
-
-            {componentProperties: {
-                value: 'foo',
-                count: 2
-              },
-              declarations: [HomeComponent],
-            }
-          );
-        }`,
-    },
-  ];
-  /* tslint:enable */
-
-  const schematicRunner = new SchematicTestRunner('migrations', require.resolve('../../migrations/migration.json'));
-  const specPath = normalize('tests/home.spec.ts');
-
-  fixtures.forEach(async ({ description, input, expected }) => {
-    it(description, async () => {
-      const host = new TempScopedNodeJsSyncHost();
-      const tree = new UnitTestTree(new HostTree(host));
-      tree.create('/package.json', JSON.stringify({}));
-      process.chdir(getSystemPath(host.root));
-      await host.write(specPath, input).toPromise();
-
-      await schematicRunner.runSchematicAsync('migration-4.0.0', {}, tree).toPromise();
-      await schematicRunner.engine.executePostTasks().toPromise();
-
-      const actual = await host.read(specPath).toPromise().then(virtualFs.fileBufferToString);
-
-      expect(actual.replace(/\s/g, '')).toBe(expected.replace(/\s/g, ''));
-    });
-  });
-});
diff --git a/projects/testing-library/tests/migration/5_1_2.spec.ts b/projects/testing-library/tests/migration/5_1_2.spec.ts
deleted file mode 100644
index b41001f2..00000000
--- a/projects/testing-library/tests/migration/5_1_2.spec.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { getSystemPath, normalize, virtualFs } from '@angular-devkit/core';
-import { TempScopedNodeJsSyncHost } from '@angular-devkit/core/node/testing';
-import { HostTree } from '@angular-devkit/schematics';
-import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
-import { stripIndents } from '@angular-devkit/core/src/utils/literals';
-
-describe('Migration to version 5.1.2', () => {
-  const schematicRunner = new SchematicTestRunner('migrations', require.resolve('../../migrations/migration.json'));
-
-  test('it renames @angular-extensions to @testing-library (in files)', async () => {
-    const specPath = normalize('tests/home.spec.ts');
-
-    const host = new TempScopedNodeJsSyncHost();
-    const tree = new UnitTestTree(new HostTree(host));
-    tree.create('/package.json', JSON.stringify({}));
-    process.chdir(getSystemPath(host.root));
-    await host
-      .write(
-        specPath,
-        virtualFs.stringToFileBuffer(stripIndents`
-          import { render } from '@angular-extensions/testing-library';
-          import { render } from "@angular-extensions/testing-library";
-        `),
-      )
-      .toPromise();
-
-    await schematicRunner.runSchematicAsync('migration-5.1.2', {}, tree).toPromise();
-    await schematicRunner.engine.executePostTasks().toPromise();
-
-    const actual = await host.read(specPath).toPromise().then(virtualFs.fileBufferToString);
-
-    expect(actual).toBe(stripIndents`
-        import { render } from '@testing-library/angular';
-        import { render } from "@testing-library/angular";
-      `);
-  });
-
-  test('it renames @angular-extensions to @testing-library (in package.json)', async () => {
-    const packageJson = normalize('/package.json');
-    const host = new TempScopedNodeJsSyncHost();
-    const tree = new UnitTestTree(new HostTree(host));
-
-    tree.create(
-      packageJson,
-      JSON.stringify({
-        devDependencies: {
-          '@angular-extensions/testing-library': '🦔',
-        },
-      }),
-    );
-
-    await schematicRunner.runSchematicAsync('migration-5.1.2', {}, tree).toPromise();
-    await schematicRunner.engine.executePostTasks().toPromise();
-
-    expect(tree.readContent(packageJson)).toBe(
-      JSON.stringify(
-        {
-          devDependencies: {
-            '@testing-library/angular': '^6.0.0',
-          },
-        },
-        null,
-        2,
-      ),
-    );
-  });
-});
diff --git a/projects/testing-library/tests/directive.spec.ts b/projects/testing-library/tests/render-template.spec.ts
similarity index 57%
rename from projects/testing-library/tests/directive.spec.ts
rename to projects/testing-library/tests/render-template.spec.ts
index 2d7f42a8..1bc4e30d 100644
--- a/projects/testing-library/tests/directive.spec.ts
+++ b/projects/testing-library/tests/render-template.spec.ts
@@ -1,8 +1,11 @@
+/* eslint-disable testing-library/no-container */
+/* eslint-disable testing-library/render-result-naming-convention */
 import { Directive, HostListener, ElementRef, Input, Output, EventEmitter, Component } from '@angular/core';
 
 import { render, fireEvent } from '../src/public_api';
 
 @Directive({
+  // eslint-disable-next-line @angular-eslint/directive-selector
   selector: '[onOff]',
 })
 export class OnOffDirective {
@@ -21,6 +24,7 @@ export class OnOffDirective {
 }
 
 @Directive({
+  // eslint-disable-next-line @angular-eslint/directive-selector
   selector: '[update]',
 })
 export class UpdateInputDirective {
@@ -32,27 +36,53 @@ export class UpdateInputDirective {
   constructor(private el: ElementRef) {}
 }
 
+@Component({
+  // eslint-disable-next-line @angular-eslint/component-selector
+  selector: 'greeting',
+  template: 'Hello {{ name }}!',
+})
+export class GreetingComponent {
+  @Input() name = 'World';
+}
+
 test('the directive renders', async () => {
-  const component = await render(OnOffDirective, {
-    template: '<div onOff></div>',
+  const component = await render('<div onOff></div>', {
+    declarations: [OnOffDirective],
   });
 
   expect(component.container.querySelector('[onoff]')).toBeInTheDocument();
 });
 
-test('uses the default props', async () => {
+test('the component renders', async () => {
+  const component = await render('<greeting name="Angular"></greeting>', {
+    declarations: [GreetingComponent],
+  });
+
+  expect(component.container.querySelector('greeting')).toBeInTheDocument();
+  expect(component.getByText('Hello Angular!'));
+});
+
+test('the directive renders (compatibility with the deprecated signature)', async () => {
   const component = await render(OnOffDirective, {
     template: '<div onOff></div>',
   });
 
+  expect(component.container.querySelector('[onoff]')).toBeInTheDocument();
+});
+
+test.only('uses the default props', async () => {
+  const component = await render('<div onOff></div>', {
+    declarations: [OnOffDirective],
+  });
+
   fireEvent.click(component.getByText('init'));
   fireEvent.click(component.getByText('on'));
   fireEvent.click(component.getByText('off'));
 });
 
 test('overrides input properties', async () => {
-  const component = await render(OnOffDirective, {
-    template: '<div onOff on="hello"></div>',
+  const component = await render('<div onOff on="hello"></div>', {
+    declarations: [OnOffDirective],
   });
 
   fireEvent.click(component.getByText('init'));
@@ -62,8 +92,8 @@ test('overrides input properties', async () => {
 
 test('overrides input properties via a wrapper', async () => {
   // `bar` will be set as a property on the wrapper component, the property will be used to pass to the directive
-  const component = await render(OnOffDirective, {
-    template: '<div onOff [on]="bar"></div>',
+  const component = await render('<div onOff [on]="bar"></div>', {
+    declarations: [OnOffDirective],
     componentProperties: {
       bar: 'hello',
     },
@@ -77,8 +107,8 @@ test('overrides input properties via a wrapper', async () => {
 test('overrides output properties', async () => {
   const clicked = jest.fn();
 
-  const component = await render(OnOffDirective, {
-    template: '<div onOff (clicked)="clicked($event)"></div>',
+  const component = await render('<div onOff (clicked)="clicked($event)"></div>', {
+    declarations: [OnOffDirective],
     componentProperties: {
       clicked,
     },
@@ -93,8 +123,8 @@ test('overrides output properties', async () => {
 
 describe('removeAngularAttributes', () => {
   test('should remove angular attributes', async () => {
-    await render(OnOffDirective, {
-      template: '<div onOff (clicked)="clicked($event)"></div>',
+    await render('<div onOff (clicked)="clicked($event)"></div>', {
+      declarations: [OnOffDirective],
       removeAngularAttributes: true,
     });
 
@@ -103,8 +133,8 @@ describe('removeAngularAttributes', () => {
   });
 
   test('is disabled by default', async () => {
-    await render(OnOffDirective, {
-      template: '<div onOff (clicked)="clicked($event)"></div>',
+    await render('<div onOff (clicked)="clicked($event)"></div>', {
+      declarations: [OnOffDirective],
     });
 
     expect(document.querySelector('[ng-version]')).not.toBeNull();
@@ -112,16 +142,15 @@ describe('removeAngularAttributes', () => {
   });
 });
 
-
 test('updates properties and invokes change detection', async () => {
-  const component = await render(UpdateInputDirective, {
-    template: '<div [update]="value" ></div>',
+  const component = await render('<div [update]="value" ></div>', {
+    declarations: [UpdateInputDirective],
     componentProperties: {
-      value: 'value1'
-    }
+      value: 'value1',
+    },
   });
 
-  component.getByText('value1')
-  component.fixture.componentInstance.value = 'updated value'
-  component.getByText('updated value')
+  component.getByText('value1');
+  component.fixture.componentInstance.value = 'updated value';
+  component.getByText('updated value');
 });
diff --git a/projects/testing-library/tests/rerender.spec.ts b/projects/testing-library/tests/rerender.spec.ts
index 0a1b9c79..5f7d152a 100644
--- a/projects/testing-library/tests/rerender.spec.ts
+++ b/projects/testing-library/tests/rerender.spec.ts
@@ -40,7 +40,7 @@ class FixtureWithNgOnChangesComponent implements OnChanges {
 test('will call ngOnChanges on rerender', async () => {
   const nameChanged = jest.fn();
   const componentProperties = { nameChanged };
-  const component = await render(FixtureWithNgOnChangesComponent, {componentProperties});
+  const component = await render(FixtureWithNgOnChangesComponent, { componentProperties });
   component.getByText('Sarah');
 
   const name = 'Mark';
@@ -50,14 +50,12 @@ test('will call ngOnChanges on rerender', async () => {
 
   component.getByText(name);
   expect(nameChanged).toBeCalledWith(name, false);
-})
+});
 
 @Component({
   changeDetection: ChangeDetectionStrategy.OnPush,
   selector: 'fixture-onpush',
-  template: `
-    <div data-testid="number" [class.active]="activeField === 'number'">Number</div>
-  `,
+  template: ` <div data-testid="number" [class.active]="activeField === 'number'">Number</div> `,
 })
 class FixtureWithOnPushComponent {
   @Input() activeField: string;
@@ -70,4 +68,4 @@ test('update properties on rerender', async () => {
   expect(numberHtmlElementRef).not.toHaveClass('active');
   rerender({ activeField: 'number' });
   expect(numberHtmlElementRef).toHaveClass('active');
-})
+});
diff --git a/projects/testing-library/tsconfig.spec.json b/projects/testing-library/tsconfig.spec.json
index ba3de654..091c5cf3 100644
--- a/projects/testing-library/tsconfig.spec.json
+++ b/projects/testing-library/tsconfig.spec.json
@@ -2,7 +2,7 @@
   "extends": "../../tsconfig.json",
   "compilerOptions": {
     "module": "commonjs",
-    "types": ["node", "jest"]
+    "types": ["node", "jest", "@testing-library/jest-dom"]
   },
   "files": ["test-setup.ts"],
   "include": ["**/*.spec.ts", "**/*.d.ts"]
diff --git a/projects/testing-library/tslint.json b/projects/testing-library/tslint.json
deleted file mode 100644
index 0946f209..00000000
--- a/projects/testing-library/tslint.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "extends": "../../tslint.json"
-}
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index 2b9e595a..00000000
--- a/tslint.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-  "rulesDirectory": ["node_modules/codelyzer"],
-  "rules": {
-    "arrow-return-shorthand": true,
-    "callable-types": true,
-    "class-name": true,
-    "comment-format": [true, "check-space"],
-    "curly": true,
-    "deprecation": {
-      "severity": "warn"
-    },
-    "eofline": true,
-    "forin": true,
-    "import-blacklist": [true, "rxjs/Rx"],
-    "import-spacing": true,
-    "indent": [true, "spaces"],
-    "interface-over-type-literal": true,
-    "label-position": true,
-    "member-access": false,
-    "member-ordering": [
-      true,
-      {
-        "order": ["static-field", "instance-field", "static-method", "instance-method"]
-      }
-    ],
-    "no-arg": true,
-    "no-bitwise": true,
-    "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
-    "no-construct": true,
-    "no-debugger": true,
-    "no-duplicate-super": true,
-    "no-empty": false,
-    "no-empty-interface": true,
-    "no-eval": true,
-    "no-inferrable-types": [true, "ignore-params"],
-    "no-misused-new": true,
-    "no-non-null-assertion": true,
-    "no-shadowed-variable": true,
-    "no-string-literal": false,
-    "no-string-throw": true,
-    "no-switch-case-fall-through": true,
-    "no-trailing-whitespace": true,
-    "no-unnecessary-initializer": true,
-    "no-unused-expression": true,
-    "no-var-keyword": true,
-    "object-literal-sort-keys": false,
-    "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
-    "prefer-const": true,
-    "quotemark": [true, "single"],
-    "radix": true,
-    "triple-equals": [true, "allow-null-check"],
-    "typedef-whitespace": [
-      true,
-      {
-        "call-signature": "nospace",
-        "index-signature": "nospace",
-        "parameter": "nospace",
-        "property-declaration": "nospace",
-        "variable-declaration": "nospace"
-      }
-    ],
-    "variable-name": false,
-    "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
-    "no-output-on-prefix": true,
-    "no-inputs-metadata-property": true,
-    "no-outputs-metadata-property": true,
-    "no-host-metadata-property": true,
-    "no-input-rename": true,
-    "no-output-rename": true,
-    "use-lifecycle-interface": true,
-    "use-pipe-transform-interface": true,
-    "component-class-suffix": true,
-    "directive-class-suffix": true
-  }
-}