diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a28a1f1
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.js]
+indent_style = space
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..3dddf3f
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+dist/*
+node_modules/*
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..3010f60
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+    extends: ['scratch', 'scratch/node', 'scratch/es6']
+};
diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
index f9f8dc2..a11f7f9 100644
--- a/.github/workflows/ci-cd.yml
+++ b/.github/workflows/ci-cd.yml
@@ -35,7 +35,9 @@ jobs:
           GitHub head ref: ${{ github.head_ref }}
           EOF
       - name: Setup
-        run: npm ci --legacy-peer-deps
+        run: npm ci
+      - name: Lint
+        run: npm run lint
       - name: Setup Deploy
         run: |
           echo "export NPM_TAG=latest" >> $GITHUB_ENV
diff --git a/package.json b/package.json
index 66485f5..b961020 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
   "scripts": {
     "build": "npm run clean && webpack --progress --bail",
     "clean": "rimraf ./dist",
+    "lint": "eslint .",
     "test": "npm run build",
     "watch": "webpack --progress --watch"
   },
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
new file mode 100644
index 0000000..a704f70
--- /dev/null
+++ b/src/.eslintrc.js
@@ -0,0 +1,7 @@
+module.exports = {
+    root: true,
+    extends: ['scratch', 'scratch/es6'],
+    env: {
+        browser: true
+    }
+};
diff --git a/src/index.js b/src/index.js
index 24e2b72..10b8817 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,41 +1,41 @@
-// Synchronously load TTF fonts.
-// First, have Webpack load their data as Base 64 strings.
-let FONTS;
-
-const getFonts = function () {
-    if (FONTS) return FONTS;
-    /* eslint-disable global-require */
-    FONTS = {
-        'Sans Serif': require('base64-loader!./NotoSans-Medium.ttf'),
-        'Serif': require('base64-loader!./SourceSerifPro-Regular.otf'),
-        'Handwriting': require('base64-loader!./handlee-regular.ttf'),
-        'Marker': require('base64-loader!./Knewave.ttf'),
-        'Curly': require('base64-loader!./Griffy-Regular.ttf'),
-        'Pixel': require('base64-loader!./Grand9K-Pixel.ttf'),
-        'Scratch': require('base64-loader!./Scratch.ttf')
-    };
-    /* eslint-enable global-require */
-
-    // For each Base 64 string,
-    // 1. Replace each with a usable @font-face tag that points to a Data URI.
-    // 2. Inject the font into a style on `document.body`, so measurements
-    //    can be accurately taken in SvgRenderer._transformMeasurements.
-    for (const fontName in FONTS) {
-        const fontData = FONTS[fontName];
-        FONTS[fontName] = '@font-face {' +
-            `font-family: "${fontName}";src: url("data:application/x-font-ttf;charset=utf-8;base64,${fontData}");}`;
-    }
-
-    if (!document.getElementById('scratch-font-styles')) {
-    	const documentStyleTag = document.createElement('style');
-    	documentStyleTag.id = 'scratch-font-styles';
-    	for (const fontName in FONTS) {
-    	    documentStyleTag.textContent += FONTS[fontName];
-    	}
-    	document.body.insertBefore(documentStyleTag, document.body.firstChild);
-    }
-
-    return FONTS;
-}
-
-module.exports = getFonts;
+// Synchronously load TTF fonts.
+// First, have Webpack load their data as Base 64 strings.
+let FONTS;
+
+const getFonts = function () {
+    if (FONTS) return FONTS;
+    /* eslint-disable global-require */
+    FONTS = {
+        'Sans Serif': require('base64-loader!./NotoSans-Medium.ttf'),
+        'Serif': require('base64-loader!./SourceSerifPro-Regular.otf'),
+        'Handwriting': require('base64-loader!./handlee-regular.ttf'),
+        'Marker': require('base64-loader!./Knewave.ttf'),
+        'Curly': require('base64-loader!./Griffy-Regular.ttf'),
+        'Pixel': require('base64-loader!./Grand9K-Pixel.ttf'),
+        'Scratch': require('base64-loader!./Scratch.ttf')
+    };
+    /* eslint-enable global-require */
+
+    // For each Base 64 string,
+    // 1. Replace each with a usable @font-face tag that points to a Data URI.
+    // 2. Inject the font into a style on `document.body`, so measurements
+    //    can be accurately taken in SvgRenderer._transformMeasurements.
+    for (const fontName in FONTS) {
+        const fontData = FONTS[fontName];
+        FONTS[fontName] = '@font-face {' +
+            `font-family: "${fontName}";src: url("data:application/x-font-ttf;charset=utf-8;base64,${fontData}");}`;
+    }
+
+    if (!document.getElementById('scratch-font-styles')) {
+        const documentStyleTag = document.createElement('style');
+        documentStyleTag.id = 'scratch-font-styles';
+        for (const fontName in FONTS) {
+            documentStyleTag.textContent += FONTS[fontName];
+        }
+        document.body.insertBefore(documentStyleTag, document.body.firstChild);
+    }
+
+    return FONTS;
+};
+
+module.exports = getFonts;