diff --git a/.circleci/config.yml b/.circleci/config.yml
index 79009713200f238f515badce4581e9894168dc52..c3517a428f3b7982f0e67c359519bce30e476cdc 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -43,25 +43,15 @@ jobs:
           when: always
           command: npm run test:js:server
 
-  danger:
-    docker:
-      - image: shieldsio/shields-ci-node-8:0.0.3
-    working_directory: ~/repo
-    steps:
-      - checkout
-
-      - restore_cache:
-          key: v1-dependencies-{{ checksum "package.json" }}
-
       - run:
           name: Integration tests
           when: always
           command: npm run test:integration
 
       - run:
-          name: Danger
+          name: 'Prettier check (quick fix: `npm run prettier`)'
           when: always
-          command: npm run danger ci
+          command: npm run prettier-check
 
   main@node-latest:
     docker:
@@ -83,6 +73,31 @@ jobs:
           when: always
           command: npm run test:js:server
 
+      - run:
+          name: Integration tests
+          when: always
+          command: npm run test:integration
+
+      - run:
+          name: 'Prettier check (quick fix: `npm run prettier`)'
+          when: always
+          command: npm run prettier-check
+
+  danger:
+    docker:
+      - image: shieldsio/shields-ci-node-8:0.0.3
+    working_directory: ~/repo
+    steps:
+      - checkout
+
+      - restore_cache:
+          key: v1-dependencies-{{ checksum "package.json" }}
+
+      - run:
+          name: Danger
+          when: always
+          command: npm run danger ci
+
   frontend:
     docker:
       - image: shieldsio/shields-ci-node-8:0.0.3
diff --git a/.eslintrc-preferred.yml b/.eslintrc-preferred.yml
index 0cde51dd641a6b6f4e9deb7fc6a2f8f62570fe95..23766a71a83633c958ccbd3d3160f49b116de4b1 100644
--- a/.eslintrc-preferred.yml
+++ b/.eslintrc-preferred.yml
@@ -1,5 +1,4 @@
 plugins:
-#   - "prettier"
   - "chai-friendly"
 
 extends:
@@ -12,8 +11,6 @@ parserOptions:
   sourceType: "script"
 
 rules:
-  # prettier/prettier: "error"
-
   # These are not disabled by eslint-config-prettier
   spaced-comment: "off"
   standard/object-curly-even-spacing: "off"
diff --git a/.prettierignore b/.prettierignore
index cd5aab3f6834feb91dc935b0cf7f3c023449204f..b2ae4bd695fe8aba3fbbf63347fbc81f68d864b3 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,3 +1,10 @@
 server.js
+dangerfile.js
+next.config.js
 server.spec.js
 package.json
+package-lock.json
+/__snapshots__
+/.next
+/build
+/coverage
diff --git a/.prettierrc.yml b/.prettierrc.yml
index 5a5e190e56812a2e25f663cf9f46a3fe5eb2327d..69e0da3e973dbfeea2f3eb117bbeb5a08913ee0e 100644
--- a/.prettierrc.yml
+++ b/.prettierrc.yml
@@ -1,3 +1,4 @@
+semi: false
 singleQuote: true
 trailingComma: es5
 bracketSpacing: true
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 291cd2009fe58136e9e70213030302c2971a8fcb..363dbbc0cca899cb5dd9217bec2e853d64fd0fa2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -108,6 +108,17 @@ Badge URLs
 Coding guidelines
 -----------------
 
+### Prettier
+
+This project formats its source code using Prettier. The most enjoyable way to
+use Prettier is to let is format code for you when you save. You can [integrate
+it into your editor][integrate prettier].
+
+If for whatever reason you don't want to do that, you can run
+`npm run prettier` to format the code from the command line.
+
+[integrate prettier]: https://prettier.io/docs/en/editors.html
+
 ### Tests
 
 When adding or changing a service [please write tests][service-tests].
diff --git a/package-lock.json b/package-lock.json
index af404825b2e4cda2d3f6c2226e82e75ad868eea5..3d8dd2a3b87023e5522744cce82648e782af9813 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -314,8 +314,7 @@
     "acorn": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
-      "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=",
-      "optional": true
+      "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
     },
     "acorn-dynamic-import": {
       "version": "2.0.2",
@@ -2415,8 +2414,7 @@
             "ansi-regex": {
               "version": "2.1.1",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "aproba": {
               "version": "1.2.0",
@@ -2437,14 +2435,12 @@
             "balanced-match": {
               "version": "1.0.0",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "brace-expansion": {
               "version": "1.1.11",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
@@ -2459,20 +2455,17 @@
             "code-point-at": {
               "version": "1.1.0",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "concat-map": {
               "version": "0.0.1",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "console-control-strings": {
               "version": "1.1.0",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "core-util-is": {
               "version": "1.0.2",
@@ -2589,8 +2582,7 @@
             "inherits": {
               "version": "2.0.3",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "ini": {
               "version": "1.3.5",
@@ -2602,7 +2594,6 @@
               "version": "1.0.0",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "number-is-nan": "^1.0.0"
               }
@@ -2617,7 +2608,6 @@
               "version": "3.0.4",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "brace-expansion": "^1.1.7"
               }
@@ -2625,14 +2615,12 @@
             "minimist": {
               "version": "0.0.8",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "minipass": {
               "version": "2.2.4",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "safe-buffer": "^5.1.1",
                 "yallist": "^3.0.0"
@@ -2651,7 +2639,6 @@
               "version": "0.5.1",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "minimist": "0.0.8"
               }
@@ -2732,8 +2719,7 @@
             "number-is-nan": {
               "version": "1.0.1",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "object-assign": {
               "version": "4.1.1",
@@ -2745,7 +2731,6 @@
               "version": "1.4.0",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "wrappy": "1"
               }
@@ -2831,8 +2816,7 @@
             "safe-buffer": {
               "version": "5.1.1",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "safer-buffer": {
               "version": "2.1.2",
@@ -2868,7 +2852,6 @@
               "version": "1.0.2",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "code-point-at": "^1.0.0",
                 "is-fullwidth-code-point": "^1.0.0",
@@ -2888,7 +2871,6 @@
               "version": "3.0.1",
               "bundled": true,
               "dev": true,
-              "optional": true,
               "requires": {
                 "ansi-regex": "^2.0.0"
               }
@@ -2932,14 +2914,12 @@
             "wrappy": {
               "version": "1.0.2",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "yallist": {
               "version": "3.0.2",
               "bundled": true,
-              "dev": true,
-              "optional": true
+              "dev": true
             }
           }
         },
@@ -3649,8 +3629,7 @@
     "cssom": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
-      "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
-      "optional": true
+      "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs="
     },
     "cssstyle": {
       "version": "0.2.37",
@@ -4733,9 +4712,9 @@
       }
     },
     "eslint-config-prettier": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.6.0.tgz",
-      "integrity": "sha1-8h2w67Q4rWePuYlGCXxLsZi+/Mw=",
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz",
+      "integrity": "sha512-ag8YEyBXsm3nmOv1Hz991VtNNDMRa+MNy8cY47Pl4bw6iuzqKbJajXdqUpiw13STdLLrznxgm1hj9NhxeOYq0A==",
       "dev": true,
       "requires": {
         "get-stdin": "^5.0.1"
@@ -4916,16 +4895,6 @@
         }
       }
     },
-    "eslint-plugin-prettier": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.3.1.tgz",
-      "integrity": "sha512-AV8shBlGN9tRZffj5v/f4uiQWlP3qiQ+lh+BhTqRLuKSyczx+HRWVkVZaf7dOmguxghAH1wftnou/JUEEChhGg==",
-      "dev": true,
-      "requires": {
-        "fast-diff": "^1.1.1",
-        "jest-docblock": "^21.0.0"
-      }
-    },
     "eslint-plugin-promise": {
       "version": "3.8.0",
       "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz",
@@ -5307,12 +5276,6 @@
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
       "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
     },
-    "fast-diff": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
-      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
-      "dev": true
-    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -6792,12 +6755,6 @@
       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
     },
-    "jest-docblock": {
-      "version": "21.2.0",
-      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
-      "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
-      "dev": true
-    },
     "jison": {
       "version": "0.4.13",
       "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
@@ -8731,7 +8688,6 @@
           "version": "0.1.4",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "kind-of": "^3.0.2",
             "longest": "^1.0.1",
@@ -9762,8 +9718,7 @@
         "longest": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "loose-envify": {
           "version": "1.3.1",
@@ -11486,6 +11441,43 @@
       "integrity": "sha512-KtQ2EGaUwf2EyDfp1fxyEb0PqGKakVm0WyXwDt6u+cAoxbO2Z2CwKvOe3+b4+F2IlO9lYHi1kqFuRM70ddBnow==",
       "dev": true
     },
+    "prettier-check": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prettier-check/-/prettier-check-2.0.0.tgz",
+      "integrity": "sha512-HZG53XQTJ9Cyi5hi1VFVVFxdlhITJybpZAch3ib9KqI05VUxV+F5Hip0GhSWRItrlDzVyqjSoDQ9KqIn7AHYyw==",
+      "dev": true,
+      "requires": {
+        "execa": "^0.6.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "execa": {
+          "version": "0.6.3",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz",
+          "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^5.0.1",
+            "get-stream": "^3.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
+          }
+        }
+      }
+    },
     "pretty": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
diff --git a/package.json b/package.json
index b6ba5bfae654cfe477d675139d832aa5b5925044..773575d2dee8fd1fb056a648443096518cb2e03f 100644
--- a/package.json
+++ b/package.json
@@ -62,6 +62,8 @@
     "coverage:report:reopen": "opn coverage/lcov-report/index.html",
     "coverage:report:open": "npm run coverage:report && npm run coverage:report:reopen",
     "lint": "eslint \"**/*.js\"",
+    "prettier": "prettier --write \"**/*.js\"",
+    "prettier-check": "prettier-check \"**/*.js\"",
     "danger": "danger",
     "test:js:frontend": "NODE_ENV=mocha mocha --require babel-polyfill --require babel-register \"frontend/**/*.spec.js\"",
     "test:js:server": "HANDLE_INTERNAL_ERRORS=false mocha \"*.spec.js\" \"lib/**/*.spec.js\" \"services/**/*.spec.js\"",
@@ -117,14 +119,13 @@
     "danger": "^3.7.13",
     "dejavu-fonts-ttf": "^2.37.3",
     "eslint": "^5.0.1",
-    "eslint-config-prettier": "^2.6.0",
+    "eslint-config-prettier": "^2.9.0",
     "eslint-config-standard": "^12.0.0-alpha.0",
     "eslint-config-standard-jsx": "^5.0.0",
     "eslint-config-standard-react": "^6.0.0",
     "eslint-plugin-chai-friendly": "^0.4.1",
     "eslint-plugin-import": "^2.8.0",
     "eslint-plugin-node": "^7.0.0",
-    "eslint-plugin-prettier": "^2.3.1",
     "eslint-plugin-promise": "^3.6.0",
     "eslint-plugin-react": "^7.6.1",
     "eslint-plugin-standard": "^3.0.1",
@@ -145,6 +146,7 @@
     "nyc": "^12.0.1",
     "opn-cli": "^3.1.0",
     "prettier": "1.14.0",
+    "prettier-check": "^2.0.0",
     "pretty": "^2.0.0",
     "prop-types": "^15.6.0",
     "react": "^16.4.2",