diff --git a/.arcconfig b/.arcconfig
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,7 +1,6 @@
 {
   "project.name" : "phabricator",
   "phabricator.uri" : "https://secure.phabricator.com/",
-  "lint.engine" : "PhabricatorLintEngine",
   "unit.engine" : "PhutilUnitTestEngine",
   "load" : ["src/"],
   "lint.xhpast.naminghook" : "PhabricatorSymbolNameLinter",
diff --git a/.arclint b/.arclint
new file mode 100644
--- /dev/null
+++ b/.arclint
@@ -0,0 +1,61 @@
+{
+  "exclude": [
+    "(^externals/)",
+    "(\\.lint-test$)"
+  ],
+  "linters": {
+    "filename": {
+      "type": "filename"
+    },
+    "javelin": {
+      "type": "javelin",
+      "include": "(\\.js$)",
+      "exclude": [
+        "(^externals/JsShrink/)",
+        "(^support/aphlict/)",
+        "(^webroot/rsrc/externals/raphael/)"
+      ]
+    },
+    "jshint": {
+      "type": "jshint",
+      "include": "(\\.js$)",
+      "exclude": [
+        "(^externals/JsShrink/)",
+        "(^webroot/rsrc/externals/raphael/)"
+      ]
+    },
+    "generated": {
+      "type": "generated"
+    },
+    "merge-conflict": {
+      "type": "merge-conflict"
+    },
+    "nolint": {
+      "type": "nolint"
+    },
+    "phutil-xhpast": {
+      "type": "phutil-xhpast",
+      "include": "(\\.php$)",
+      "phutil-xhpast.deprecated.functions": {
+        "phutil_escape_html": "The phutil_escape_html() function is deprecated. Raw strings passed to phutil_tag() or hsprintf() are escaped automatically."
+      }
+    },
+    "text": {
+      "type": "text"
+    },
+    "spelling": {
+      "type": "spelling"
+    },
+    "xhpast": {
+      "type": "xhpast",
+      "include": "(\\.php$)",
+      "severity": {
+        "16": "advice",
+        "29": "warning",
+        "31": "error",
+        "34": "error",
+        "35": "error"
+      }
+    }
+  }
+}
diff --git a/src/infrastructure/lint/PhabricatorLintEngine.php b/src/infrastructure/lint/PhabricatorLintEngine.php
deleted file mode 100644
--- a/src/infrastructure/lint/PhabricatorLintEngine.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-/**
- * @concrete-extensible
- */
-class PhabricatorLintEngine extends PhutilLintEngine {
-
-  public function buildLinters() {
-    $linters = parent::buildLinters();
-
-    foreach ($linters as $linter) {
-      if ($linter instanceof ArcanistPhutilXHPASTLinter) {
-        $linter->setDeprecatedFunctions(array(
-          'phutil_escape_html' =>
-            'The phutil_escape_html() function is deprecated. Raw strings '.
-            'passed to phutil_tag() or hsprintf() are escaped automatically.',
-        ));
-      }
-    }
-
-    $paths = $this->getPaths();
-
-    foreach ($paths as $key => $path) {
-      if (!$this->pathExists($path)) {
-        unset($paths[$key]);
-      }
-    }
-
-    $javelin_linter = new PhabricatorJavelinLinter();
-    $linters[] = $javelin_linter;
-
-    $jshint_linter = new ArcanistJSHintLinter();
-    $linters[] = $jshint_linter;
-
-    foreach ($paths as $path) {
-      if (!preg_match('/\.js$/', $path)) {
-        continue;
-      }
-
-      if (strpos($path, 'externals/JsShrink') !== false) {
-        // Ignore warnings in JsShrink tests.
-        continue;
-      }
-
-      if (strpos($path, 'externals/raphael') !== false) {
-        // Ignore Raphael.
-        continue;
-      }
-
-      $jshint_linter->addPath($path);
-      $jshint_linter->addData($path, $this->loadData($path));
-
-      if (strpos($path, 'support/aphlict/') !== false) {
-        // This stuff is Node.js, not Javelin, so don't apply the Javelin
-        // linter.
-        continue;
-      }
-
-      $javelin_linter->addPath($path);
-      $javelin_linter->addData($path, $this->loadData($path));
-    }
-
-    return $linters;
-  }
-
-}
diff --git a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
--- a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
+++ b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
@@ -48,6 +48,10 @@
     return 'JAVELIN';
   }
 
+  public function getLinterConfigurationName() {
+    return 'javelin';
+  }
+
   public function getLintSeverityMap() {
     return array(
       self::LINT_MISSING_BINARY => ArcanistLintSeverity::SEVERITY_WARNING,