diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd27efce3c624234b83a897d7f20a0242b2c9e8a
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,65 @@
+{
+    "env": {
+        "browser": true,
+        "node": true
+    },
+    "parser": "@typescript-eslint/parser",
+    "parserOptions": {
+        "project": "tsconfig.json",
+        "sourceType": "module"
+    },
+    "plugins": [
+        "@typescript-eslint"
+    ],
+    "rules": {
+        "@typescript-eslint/ban-types": "warn",
+        "@typescript-eslint/class-name-casing": "off",
+        "@typescript-eslint/indent": [
+            "warn",
+            4
+        ],
+        "@typescript-eslint/member-delimiter-style": [
+            "off",
+            {
+                "multiline": {
+                    "delimiter": "none",
+                    "requireLast": true
+                },
+                "singleline": {
+                    "delimiter": "semi",
+                    "requireLast": false
+                }
+            }
+        ],
+        "@typescript-eslint/prefer-namespace-keyword": "warn",
+        "@typescript-eslint/quotes": [
+            "warn",
+            "single",
+            { 
+                "avoidEscape": true,
+                "allowTemplateLiterals": true
+            }
+        ],
+        "@typescript-eslint/semi": [
+            "off",
+            null
+        ],
+        "@typescript-eslint/type-annotation-spacing": "warn",
+        "arrow-parens": [
+            "off",
+            "as-needed"
+        ],
+        "comma-dangle": "off",
+        "eqeqeq": [
+            "warn",
+            "smart"
+        ],
+        "import/order": "off",
+        "no-eval": "warn",
+        "no-new-wrappers": "warn",
+        "no-trailing-spaces": "warn",
+        "no-unsafe-finally": "warn",
+        "no-var": "warn",
+        "spaced-comment": "warn"
+    }
+}
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index ed23e91023d6c7b91627b4c2bf40e018e6eb41d2..966b67347d36bc37436d3ba78525db8a5a4275fc 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -4,8 +4,8 @@
 
 	// List of extensions which should be recommended for users of this workspace.
 	"recommendations": [
+		"dbaeumer.vscode-eslint",
 		"firsttris.vscode-jest-runner",
-		"ms-vscode.vscode-typescript-tslint-plugin",
 		"msjsdiag.debugger-for-chrome",
 		"slevesque.shader",
 		"stpn.vscode-graphql",
diff --git a/package-lock.json b/package-lock.json
index 5c109f4147d46e40c6680d6f72eab9c05ea37412..dbe62bc9d3fc81fc2046b676f1241e909e9ed774 100644
Binary files a/package-lock.json and b/package-lock.json differ
diff --git a/package.json b/package.json
index 35d015648e3472f671df944640d1e8cff7b8e4db..69a90445f6f511b5ecd42fb505525394722ed15f 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
     "url": "https://github.com/molstar/molstar/issues"
   },
   "scripts": {
-    "lint": "tslint src/**/*.ts",
+    "lint": "eslint src/**/*.ts",
     "test": "npm run lint && jest",
     "build": "npm run build-tsc && npm run build-extra && npm run build-webpack",
     "build-tsc": "tsc",
@@ -63,11 +63,15 @@
   ],
   "license": "MIT",
   "devDependencies": {
+    "@typescript-eslint/eslint-plugin": "^2.13.0",
+    "@typescript-eslint/eslint-plugin-tslint": "^2.13.0",
+    "@typescript-eslint/parser": "^2.13.0",
     "benchmark": "^2.1.4",
     "circular-dependency-plugin": "^5.2.0",
     "concurrently": "^5.0.1",
     "cpx": "^1.5.0",
     "css-loader": "^3.3.2",
+    "eslint": "^6.8.0",
     "extra-watch-webpack-plugin": "^1.0.3",
     "file-loader": "^5.0.2",
     "fs-extra": "^8.1.0",
@@ -85,7 +89,6 @@
     "simple-git": "^1.129.0",
     "style-loader": "^1.0.1",
     "ts-jest": "^24.2.0",
-    "tslint": "^5.20.1",
     "typescript": "^3.7.3",
     "webpack": "^4.41.3",
     "webpack-cli": "^3.3.10"
diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts
index 7a0b18d842e6ddde83150c73c80ebc454025b1f5..de17fbbb7dc8d8ac5f762565a512596b60fbf6fd 100644
--- a/src/mol-state/state.ts
+++ b/src/mol-state/state.ts
@@ -680,8 +680,8 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
     }
 
     let parentCell = transform.transformer.definition.from.length === 0
-    ? ctx.cells.get(current.transform.parent)
-    : StateSelection.findAncestorOfType(tree, ctx.cells, currentRef, transform.transformer.definition.from);
+        ? ctx.cells.get(current.transform.parent)
+        : StateSelection.findAncestorOfType(tree, ctx.cells, currentRef, transform.transformer.definition.from);
     if (!parentCell) {
         throw new Error(`No suitable parent found for '${currentRef}'`);
     }
diff --git a/src/mol-state/transformer.ts b/src/mol-state/transformer.ts
index 602415646bb36d400099959ccb5380d8498220c5..459b77a69ebc593320f66ab9522f0124df77a18d 100644
--- a/src/mol-state/transformer.ts
+++ b/src/mol-state/transformer.ts
@@ -190,13 +190,13 @@ namespace Transformer {
                 display: typeof info.display === 'string'
                     ? { name: info.display }
                     : !!info.display
-                    ? info.display
-                    : { name: capitalize(info.name.replace(/[-]/g, ' ')) },
+                        ? info.display
+                        : { name: capitalize(info.name.replace(/[-]/g, ' ')) },
                 params: typeof info.params === 'object'
                     ? () => info.params as any
                     : !!info.params
-                    ? info.params as any
-                    : void 0,
+                        ? info.params as any
+                        : void 0,
                 ...def
             });
         }
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index ecf0639ee5c4ae7ba5c27ed412efe60d3867995c..0000000000000000000000000000000000000000
--- a/tslint.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
-    "rules": {
-        "array-type": [
-            true,
-            "array"
-        ],
-        "arrow-parens": false,
-        "no-var-keyword": true,
-        "no-construct": true,
-        "ordered-imports": [false],
-        "trailing-comma": [false],
-        "class-name": false,
-        "comment-format": [
-            true,
-            "check-space"
-        ],
-        "indent": [
-            true,
-            "spaces"
-        ],
-        "ban-types": [
-            true,
-            ["String", "Use primitive 'string' instead."],
-            ["Boolean", "Use primitive 'boolean' instead."],
-            ["Number", "Use primitive 'number' instead."]
-        ],
-        "no-eval": true,
-        "no-internal-module": true,
-        "no-trailing-whitespace": true,
-        "no-unsafe-finally": true,
-        "one-line": [
-            true,
-            "check-open-brace",
-            "check-whitespace"
-        ],
-        "quotemark": [
-            true,
-            "single"
-        ],
-        "semicolon": [ false ],
-        "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": [
-            true,
-            "ban-keywords"
-        ],
-        "whitespace": [
-            true,
-            "check-branch",
-            "check-decl",
-            "check-separator",
-            "check-type"
-        ]
-    },
-    "jsRules": {
-        "triple-equals": [
-            true,
-            "allow-null-check"
-        ]
-    },
-    "defaultSeverity": "warning"
-}
\ No newline at end of file