diff --git a/.cspell.json b/.cspell.json
index 6b30bf254bdf..0516d1196d70 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -103,6 +103,7 @@
"typedef",
"typedefs",
"unfixable",
+ "unoptimized",
"unprefixed",
"Zacher"
],
diff --git a/README.md b/README.md
index c507cd8460a7..df0c05c590ef 100644
--- a/README.md
+++ b/README.md
@@ -20,21 +20,16 @@
👆
----
-
## Packages included in this project
-- [`@typescript-eslint/eslint-plugin`](./packages/eslint-plugin/) - An ESLint-plugin with many lint rules for TypeScript features, as well as type-aware lint rules.
-
-- [`@typescript-eslint/parser`](./packages/parser/) - A ESLint-parser which enables ESLint to be able to understand TypeScript syntax. It's powered by our `typescript-estree` package.
-
-- [`@typescript-eslint/eslint-plugin-tslint`](./packages/eslint-plugin-tslint) - An ESLint-plugin that allows you to bridge ESLint and TSLint to help you migrate from TSLint to ESLint.
-
-- [`@typescript-eslint/experimental-utils`](./packages/experimental-utils) - Public utilities for working ESLint and for writing ESLint-plugins in TypeScript.
-
-- [`@typescript-eslint/typescript-estree`](./packages/typescript-estree/) - A parser which takes TypeScript source code and produces an [ESTree](https://github.com/estree/estree)-compatible AST.
+See https://typescript-eslint.io/docs/development/architecture/packages for more details.
-- [`@typescript-eslint/scope-manager`](./packages/scope-manager) - An [`eslint-scope`](https://github.com/eslint/eslint-scope)-compatible scope analyser that can understand TypeScript language features such as types, enums and namespaces.
+- [`@typescript-eslint/eslint-plugin`](./packages/eslint-plugin)
+- [`@typescript-eslint/parser`](./packages/parser)
+- [`@typescript-eslint/eslint-plugin-tslint`](./packages/eslint-plugin-tslint)
+- [`@typescript-eslint/experimental-utils`](./packages/experimental-utils)
+- [`@typescript-eslint/typescript-estree`](./packages/typescript-estree)
+- [`@typescript-eslint/scope-manager`](./packages/scope-manager)
## Versioning
diff --git a/docs/getting-started/README.md b/docs/README.md
similarity index 78%
rename from docs/getting-started/README.md
rename to docs/README.md
index 55d6c068521c..aa14517ebd62 100644
--- a/docs/getting-started/README.md
+++ b/docs/README.md
@@ -10,4 +10,4 @@ The docs are broken down into the following categories:
- [I want to lint my TypeScript codebase.](./linting/README.md)
-- [(TODO) I want to write an ESLint plugin in TypeScript.](./plugin-development/README.md)
+- [I want to develop an ESLint plugin in TypeScript.](./development/CUSTOM_RULES.md)
diff --git a/docs/development/CUSTOM_RULES.md b/docs/development/CUSTOM_RULES.md
new file mode 100644
index 000000000000..2c235725f5c7
--- /dev/null
+++ b/docs/development/CUSTOM_RULES.md
@@ -0,0 +1,268 @@
+---
+id: custom-rules
+sidebar_label: Custom Rules
+title: Custom Rules
+---
+
+:::important
+You should be familiar with [ESLint's developer guide](https://eslint.org/docs/developer-guide) and [Development > Architecture](./architecture/asts) before writing custom rules.
+:::
+
+As long as you are using `@typescript-eslint/parser` as the `parser` in your ESLint configuration, custom ESLint rules generally work the same way for JavaScript and TypeScript code.
+The main two changes to custom rules writing are:
+
+- [AST Extensions](#ast-extensions): targeting TypeScript-specific syntax in your rule selectors
+- [Typed Rules](#typed-rules): using the TypeScript type checker to inform rule logic
+
+## AST Extensions
+
+`@typescript-eslint/estree` creates AST nodes for TypeScript syntax with names that begin with `TS`, such as `TSInterfaceDeclaration` and `TSTypeAnnotation`.
+These nodes are treated just like any other AST node.
+You can query for them in your rule selectors.
+
+This rule written in JavaScript bans interfaces that start with a lower-case letter:
+
+```js
+export const rule = {
+ create(context) {
+ return {
+ TSInterfaceDeclaration(node) {
+ if (/[a-z]/.test(node.id.name[0])) {
+ context.report({
+ messageId: 'uppercase',
+ node: node.id,
+ });
+ }
+ },
+ };
+ },
+ meta: {
+ docs: {
+ category: 'Best Practices',
+ description: 'Interface names should start with an upper-case letter.',
+ },
+ messages: {
+ uppercase: 'Start this name with an upper-case letter.',
+ },
+ type: 'suggestion',
+ schema: [],
+ },
+};
+```
+
+### Writing Rules in TypeScript
+
+The `@typescript-eslint/experimental-utils` package acts as a replacement package for `eslint` that exports all the same objects and types, but with typescript-eslint support.
+
+:::caution
+`@types/eslint` types are based on `@types/estree` and do not recognize typescript-eslint nodes and properties.
+You should generally not need to import from `eslint` when writing custom typescript-eslint rules in TypeScript.
+:::
+
+#### Rule Types
+
+`@typescript-eslint/experimental-utils` exports a `RuleModule` interface that allows specifying generics for:
+
+- `MessageIds`: a union of string literal message IDs that may be reported
+- `Options`: what options users may configure for the rule
+
+```ts
+import { TSESLint } from '@typescript-eslint/experimental-utils';
+
+export const rule: TSESLint.RuleModule<'uppercase', []> = {
+ create(context /* : Readonly> */) {
+ // ...
+ },
+};
+```
+
+For groups of rules that share a common documentation URL, a `RuleCreator` function is exported.
+It takes in a function that transforms a rule name into its documentation URL, then returns a function that takes in a rule module object.
+The returned function is able to infer message IDs from `meta.messages`.
+
+```ts
+import { ESLintUtils } from '@typescript-eslint/experimental-utils';
+
+const createRule = ESLintUtils.RuleCreator(
+ name => `https://example.com/rule/${name}`,
+);
+
+// Type: const rule: RuleModule<"uppercase", ...>
+export const rule = createRule({
+ create(context) {
+ // ...
+ },
+ meta: {
+ messages: {
+ uppercase: 'Start this name with an upper-case letter.',
+ },
+ // ...
+ },
+});
+```
+
+#### Node Types
+
+TypeScript types for nodes exist in a `TSESTree` namespace exported by `@typescript-eslint/experimental-utils`.
+The above rule body could be better written in TypeScript with a type annotation on the `node`:
+
+```ts
+import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
+
+// ...
+
+export const rule = createRule({
+ create(context) {
+ return {
+ TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) {
+ // ...
+ },
+ };
+ },
+ // ...
+});
+```
+
+An `AST_NODE_TYPES` enum is exported as well to hold the values for AST node `type` properties.
+`TSESTree.Node` is available as union type that uses its `type` member as a discriminant.
+
+For example, checking `node.type` can narrow down the type of the `node`:
+
+```ts
+import {
+ AST_NODE_TYPES,
+ TSESTree,
+} from '@typescript-eslint/experimental-utils';
+
+export function describeNode(node: TSESTree.Node): string {
+ switch (node.type) {
+ case AST_NODE_TYPES.ArrayExpression:
+ return `Array containing ${node.elements.map(describeNode).join(', ')}`;
+
+ case AST_NODE_TYPES.Literal:
+ return `Literal value ${node.raw}`;
+
+ default:
+ return '🤷';
+ }
+}
+```
+
+## Type Checking
+
+:::tip
+Read TypeScript's [Compiler APIs > Using the Type Checker](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#using-the-type-checker) section for how to use a program's type checker.
+:::
+
+The biggest addition typescript-eslint brings to ESLint rules is the ability to use TypeScript's type checker APIs.
+
+`@typescript-eslint/experimental-utils` exports an `ESLintUtils` namespace containing a `getParserServices` function that takes in an ESLint context and returns a `parserServices` object.
+
+That `parserServices` object contains:
+
+- `program`: A full TypeScript `ts.Program` object
+- `esTreeNodeToTSNodeMap`: Map of `@typescript-eslint/estree` `TSESTree.Node` nodes to their TypeScript `ts.Node` equivalents
+- `tsNodeToESTreeNodeMap`: Map of TypeScript `ts.Node` nodes to their `@typescript-eslint/estree` `TSESTree.Node` equivalents
+
+By mapping from ESTree nodes to TypeScript nodes and retrieving the TypeScript program from the parser services, rules are able to ask TypeScript for full type information on those nodes.
+
+This rule bans for-of looping over an enum by using the type-checker via typescript-eslint and TypeScript APIs:
+
+```ts
+import { ESLintUtils } from '@typescript-eslint/experimental-utils';
+import * as ts from 'typescript';
+import * as tsutils from 'tsutils';
+
+export const rule: eslint.Rule.RuleModule = {
+ create(context) {
+ return {
+ ForOfStatement(node) {
+ // 1. Grab the TypeScript program from parser services
+ const parserServices = ESLintUtils.getParserServices(context);
+ const checker = parserServices.program.getTypeChecker();
+
+ // 2. Find the backing TS node for the ES node, then that TS type
+ const originalNode = parserServices.esTreeNodeToTSNodeMap.get(
+ node.right,
+ );
+ const nodeType = checker.getTypeAtLocation(node);
+
+ // 3. Check the TS node type using the TypeScript APIs
+ if (tsutils.isTypeFlagSet(nodeType, ts.TypeFlags.EnumLike)) {
+ context.report({
+ messageId: 'loopOverEnum',
+ node: node.right,
+ });
+ }
+ },
+ };
+ },
+ meta: {
+ docs: {
+ category: 'Best Practices',
+ description: 'Avoid looping over enums.',
+ },
+ messages: {
+ loopOverEnum: 'Do not loop over enums.',
+ },
+ type: 'suggestion',
+ schema: [],
+ },
+};
+```
+
+## Testing
+
+`@typescript-eslint/experimental-utils` exports a `RuleTester` with a similar API to the built-in [ESLint `RuleTester`](https://eslint.org/docs/developer-guide/nodejs-api#ruletester).
+It should be provided with the same `parser` and `parserOptions` you would use in your ESLint configuration.
+
+### Testing Untyped Rules
+
+For rules that don't need type information, passing just the `parser` will do:
+
+```ts
+import { ESLintUtils } from '@typescript-eslint/experimental-utils';
+import rule from './my-rule';
+
+const ruleTester = new ESLintUtils.RuleTester({
+ parser: '@typescript-eslint/parser',
+});
+
+ruleTester.run('my-rule', rule {
+ valid: [/* ... */],
+ invalid: [/* ... */],
+});
+```
+
+### Testing Typed Rules
+
+For rules that do need type information, `parserOptions` must be passed in as well.
+Tests must have at least an absolute `tsconfigRootDir` path provided as well as a relative `project` path from that directory:
+
+```ts
+import { ESLintUtils } from '@typescript-eslint/experimental-utils';
+import rule from './my-typed-rule';
+
+const ruleTester = new ESLintUtils.RuleTester({
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ project: './tsconfig.json',
+ tsconfigRootDir: __dirname,
+ }
+});
+
+ruleTester.run('my-typed-rule', rule {
+ valid: [/* ... */],
+ invalid: [/* ... */],
+});
+```
+
+:::note
+For now, `ESLintUtils.RuleTester` requires the following physical files be present on disk for typed rules:
+
+- `tsconfig.json`: tsconfig used as the test "project"
+- One of the following two files:
+ - `file.ts`: blank test file used for normal TS tests
+ - `file.tsx`: blank test file used for tests with `parserOptions: { ecmaFeatures: { jsx: true } }`
+
+:::
diff --git a/docs/development/architecture/ASTS.md b/docs/development/architecture/ASTS.md
new file mode 100644
index 000000000000..055ffa713d8b
--- /dev/null
+++ b/docs/development/architecture/ASTS.md
@@ -0,0 +1,51 @@
+---
+id: asts
+title: ASTs
+sidebar_label: ASTs
+---
+
+## Abstract Syntax Trees (AST)s
+
+Parsers such as those in ESLint and TypeScript read in the text of source code and parse it into a standard format they can reason about known as an **Abstract Syntax Tree** (AST).
+ASTs are called such because although they might contain information on the location of constructs within source code, they are an abstract representation that cares more about the semantic structure.
+
+For example, given this line of code:
+
+```js
+1 + 2;
+```
+
+ESLint would natively understand it as an object like:
+
+```json
+{
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "left": {
+ "type": "Literal",
+ "value": 1,
+ "raw": "1"
+ },
+ "operator": "+",
+ "right": {
+ "type": "Literal",
+ "value": 2,
+ "raw": "2"
+ }
+ }
+}
+```
+
+ESLint uses an AST format known as **[`estree`]**.
+
+ESTree is more broadly used than just for ESLint -- it is the de facto community standard.
+ESLint's built-in parser that outputs an `estree`-shaped AST is also a separate package, called **[`espree`]**.
+
+:::note
+You can play more with various ASTs such as ESTree on [astexplorer.net] and read more details on their [Wikipedia article](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
+:::
+
+[astexplorer.net]: https://astexplorer.net
+[`espree`]: https://github.com/eslint/espree
+[`estree`]: https://github.com/estree/estree
diff --git a/docs/development/architecture/PACKAGES.md b/docs/development/architecture/PACKAGES.md
new file mode 100644
index 000000000000..7e169187423e
--- /dev/null
+++ b/docs/development/architecture/PACKAGES.md
@@ -0,0 +1,78 @@
+---
+id: packages
+title: Packages
+sidebar_label: Packages
+---
+
+This page describes the top-level packages exported by the [typescript-eslint monorepo](https://github.com/typescript-eslint/typescript-eslint).
+Each of these are published as npm packages under the `@typescript-eslint` organization.
+
+## `@typescript-eslint/eslint-plugin`
+
+[`@typescript-eslint/eslint-plugin`] is the core [ESLint plugin](https://eslint.org/docs/user-guide/configuring/plugins) used by consumers to load in custom rules and rule configurations lists from typescript-eslint.
+Those rules rely on ESLint using the `@typescript-eslint/parser` package described below, and are generally built using the other packages on this page.
+
+## `@typescript-eslint/parser`
+
+[`@typescript-eslint/parser`] takes in ESLint configuration settings, reads in TypeScript source text, and produces an ESTree AST.
+This is necessary because TypeScript produces a different, incompatible AST format to the one that ESLint requires to work.
+
+For example, this is not valid JavaScript code because it contains the `: number` type annotation:
+
+```ts
+let x: number = 1;
+```
+
+ESLint's native Espree parser would raise an error attempting to parse it.
+
+Additionally, because TypeScript is developed separately and with different goals from ESLint, ESTree, and Espree, its AST also represents nodes differently in many cases.
+TS's AST is optimized for its use case of parsing incomplete code and typechecking.
+ESTree is unoptimized and intended for "general purpose" use-cases of traversing the AST.
+
+See more on configuring custom parsers with ESLint on [ESLint's User Guide > Configuring > Plugins](https://eslint.org/docs/user-guide/configuring/plugins#specifying-parser).
+
+:::tip
+You can select `@typescript-eslint/parser` on [astexplorer.net](https://astexplorer.net)'s top-middle âš™ dropdown that defaults to Acorn.
+:::
+
+## `@typescript-eslint/typescript-estree`
+
+[`@typescript-eslint/typescript-estree`] is used by `@typescript-eslint/parser` to take TypeScript source code and produce the equivalent ESTree AST.
+It works by:
+
+1. Invoking the TypeScript compiler on the given source code in order to
+ produce a TypeScript AST
+2. Converting that TypeScript AST into an ESTree AST
+
+> Because [`@typescript-eslint/typescript-estree`] has a very specific purpose, it is reusable for tools with similar
+> requirements to ESLint.
+> It is therefore also used to power the amazing opinionated code formatter [Prettier](https://prettier.io)'s TypeScript support.
+
+## `@typescript-eslint/scope-manager`
+
+[`@typescript-eslint/scope-manager`] is a fork of [`eslint-scope`](https://github.com/eslint/eslint-scope), enhanced to support TypeScript functionality.
+
+A "scope analyser" traverses an AST and builds a model of how variables (and in our case, types) are defined and consumed by the source code.
+This form of static analysis allows you to understand and trace variables throughout the program, allowing you to access powerful information about a program without needing to drop into the much, much heavier type information.
+
+## `@typescript-eslint/experimental-utils`
+
+[`@typescript-eslint/experimental-utils`] contains public utilities for writing custom rules and plugins in TypeScript.
+Rules declared in `@typescript-eslint/eslint-plugin` are created using its utility functions.
+Any custom rules you write generally will be as well.
+
+## `@typescript-eslint/eslint-plugin-tslint`
+
+[`@typescript-eslint/eslint-plugin-tslint`] is a separate ESLint plugin that allows running TSLint rules within ESLint to help you migrate from TSLint to ESLint.
+
+:::caution
+**TSLint is deprecated.** It is in your best interest to migrate off it entirely. See [Linting > TSLint](../../linting/TSLINT.md).
+:::
+
+[`@typescript-eslint/eslint-plugin-tslint`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin-tslint
+[`@typescript-eslint/eslint-plugin`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin
+[`@typescript-eslint/experimental-utils`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/experimental-utils
+[`@typescript-eslint/parser`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser
+[`@typescript-eslint/scope-manager`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/scope-manager
+[`@typescript-eslint/typescript-estree`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree
+[`@typescript-eslint/typescript-estree`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree
diff --git a/docs/getting-started/linting/ARCHITECTURE.md b/docs/getting-started/linting/ARCHITECTURE.md
deleted file mode 100644
index fb21504303c4..000000000000
--- a/docs/getting-started/linting/ARCHITECTURE.md
+++ /dev/null
@@ -1,100 +0,0 @@
----
-id: architecture
-title: Architecture
-sidebar_label: Architecture
----
-
-## Abstract Syntax Trees (AST)s
-
-Parsers such as those in ESLint and TypeScript read in the text of source code and parse it into a standard format they can reason about.
-ASTs are called such because although they might contain information on the location of constructs within source code, they are an abstract representation that cares more about the semantic structure.
-
-For example, given this line of code:
-
-```js
-1 + 2;
-```
-
-ESLint would natively understand it as an object like:
-
-```json
-{
- "type": "ExpressionStatement",
- "expression": {
- "type": "BinaryExpression",
- "left": {
- "type": "Literal",
- "value": 1,
- "raw": "1"
- },
- "operator": "+",
- "right": {
- "type": "Literal",
- "value": 2,
- "raw": "2"
- }
- }
-}
-```
-
-ESLint uses an AST format known as **[`estree`]**.
-
-ESTree is more broadly used than just for ESLint -- it is the de facto community standard.
-ESLint' built-in parser that outputs an `estree`-shaped AST is also a separate package, called **[`espree`]**.
-
-:::note
-You can play more with various ASTs such as ESTree on [astexplorer.net] and read more details on their [Wikipedia article](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
-:::
-
-## `@typescript-eslint/parser`
-
-TypeScript produces a different AST format to the one that ESLint requires to work.
-This means that by default, the TypeScript AST is not compatible with ESLint.
-
-For example:
-
-```ts
-let x: number = 1;
-```
-
-That is not valid JavaScript code because it contains the `: number` type annotation.
-ESLint's native Espree parser would raise an error attempting to parse it.
-
-Additionally, because TypeScript is developed separately from ESLint, ESTree, and Espree, its AST also represents nodes differently in many cases.
-Many nodes have different names or different member structures.
-
-[`@typescript-eslint/parser`] is a parser that takes in ESLint configuration settings, reads in TypeScript source text, and produces an ESTree AST.
-
-ESLint allows specifying custom parsers such as `@typescript-eslint/parser`.
-See more on https://eslint.org/docs/user-guide/configuring/plugins#specifying-parser.
-
-:::note
-You can select the `@typescript-eslint/parser` on the top-middle âš™ dropdown in [astexplorer.net] that defaults to Acorn.
-:::
-
-### `@typescript-eslint/typescript-estree`
-
-[`@typescript-eslint/typescript-estree`] is the utility package used by `@typescript-eslint/parser` to take TypeScript source code and produce the equivalent ESTree AST.
-It works by:
-
-1. Invoking the TypeScript compiler on the given source code in order to
- produce a TypeScript AST
-2. Converting that TypeScript AST into an ESTree AST
-
-> Because [`@typescript-eslint/typescript-estree`] has a very specific purpose, it is reusable for tools with similar
-> requirements to ESLint.
-> It is therefore also used to power the amazing opinionated code formatter [Prettier](https://prettier.io)'s TypeScript support.
-
-### `@typescript-eslint/scope-manager`
-
-`@typescript-eslint/scope-manager` is a fork of [`eslint-scope`](https://github.com/eslint/eslint-scope), enhanced to support TypeScript functionality.
-
-A "scope analyser" traverses an AST and builds a model of how variables (and in our case, types) are defined and consumed by the source code.
-This form of static analysis allows you to understand and trace variables throughout the program, allowing you to access powerful information about a program without needing to drop into the much, much heavier type information.
-
-[`@typescript-eslint/parser`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser
-[`@typescript-eslint/scope-manager`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/scope-manager
-[`@typescript-eslint/typescript-estree`]: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree
-[astexplorer.net]: https://astexplorer.net
-[`espree`]: https://github.com/eslint/espree
-[`estree`]: https://github.com/estree/estree
diff --git a/docs/getting-started/plugin-development/README.md b/docs/getting-started/plugin-development/README.md
deleted file mode 100644
index 7484b2f26a71..000000000000
--- a/docs/getting-started/plugin-development/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-id: plugins
-title: Writing an ESLint Plugin in TypeScript
-sidebar_label: Writing an ESLint Plugin in TypeScript
----
-
-TODO:
-
-- talk about how to setup the folder structure
-- talk about how to consume `experimental-utils` to create an empty rule
-- talk about https://eslint.org/docs/developer-guide/selectors and how to use the strict types
-- talk about how to write tests
-
-TODO: (advanced)
-
-- talk about how to use type information
diff --git a/docs/getting-started/linting/MONOREPO.md b/docs/linting/MONOREPO.md
similarity index 100%
rename from docs/getting-started/linting/MONOREPO.md
rename to docs/linting/MONOREPO.md
diff --git a/docs/getting-started/linting/README.md b/docs/linting/README.md
similarity index 100%
rename from docs/getting-started/linting/README.md
rename to docs/linting/README.md
diff --git a/docs/getting-started/linting/TROUBLESHOOTING.md b/docs/linting/TROUBLESHOOTING.md
similarity index 100%
rename from docs/getting-started/linting/TROUBLESHOOTING.md
rename to docs/linting/TROUBLESHOOTING.md
diff --git a/docs/getting-started/linting/TSLINT.md b/docs/linting/TSLINT.md
similarity index 100%
rename from docs/getting-started/linting/TSLINT.md
rename to docs/linting/TSLINT.md
diff --git a/docs/getting-started/linting/TYPED_LINTING.md b/docs/linting/TYPED_LINTING.md
similarity index 100%
rename from docs/getting-started/linting/TYPED_LINTING.md
rename to docs/linting/TYPED_LINTING.md
diff --git a/packages/website/docusaurus.config.js b/packages/website/docusaurus.config.js
index b8d59f357d29..9388a4b85bcb 100644
--- a/packages/website/docusaurus.config.js
+++ b/packages/website/docusaurus.config.js
@@ -105,6 +105,10 @@ const config = {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
+ tableOfContents: {
+ maxHeadingLevel: 4,
+ minHeadingLevel: 2,
+ },
}),
};
diff --git a/packages/website/sidebars/sidebar.base.js b/packages/website/sidebars/sidebar.base.js
index c68cc0193835..5d50b266eef5 100644
--- a/packages/website/sidebars/sidebar.base.js
+++ b/packages/website/sidebars/sidebar.base.js
@@ -1,26 +1,33 @@
module.exports = {
- docs: {
- Guides: [
- 'getting-started/README',
- {
- type: 'category',
- label: 'Linting',
- collapsed: false,
- items: [
- 'getting-started/linting/linting',
- 'getting-started/linting/type-linting',
- 'getting-started/linting/monorepo',
- 'getting-started/linting/troubleshooting',
- 'getting-started/linting/architecture',
- 'getting-started/linting/tslint',
- ],
- },
- {
- type: 'category',
- label: 'Plugins',
- collapsed: false,
- items: ['getting-started/plugin-development/plugins'],
- },
- ],
- },
+ docs: [
+ 'README',
+ {
+ type: 'category',
+ label: 'Linting',
+ collapsed: false,
+ items: [
+ 'linting/linting',
+ 'linting/type-linting',
+ 'linting/monorepo',
+ 'linting/troubleshooting',
+ 'linting/tslint',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Development',
+ collapsed: false,
+ items: [
+ {
+ label: 'Architecture',
+ type: 'category',
+ items: [
+ 'development/architecture/asts',
+ 'development/architecture/packages',
+ ],
+ },
+ 'development/custom-rules',
+ ],
+ },
+ ],
};