diff --git a/.eslintrc.js b/.eslintrc.js
index e917e67b92867..2c4a86dda0b11 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -100,9 +100,10 @@ module.exports = {
         ...TSEslint.configs.recommended.rules,
         // We should absolutely avoid using ts-ignore, but it's not always possible.
         // particular when a dependencies types are incorrect.
-        "@typescript-eslint/ban-ts-comment": {
-          "ts-ignore": "allow-with-description",
-        },
+        "@typescript-eslint/ban-ts-comment": [
+          "warn",
+          { "ts-ignore": "allow-with-description" }
+        ],
         // This rule is great. It helps us not throw on types for areas that are
         // easily inferrable. However we have a desire to have all function inputs
         // and outputs declaratively typed. So this let's us ignore the parameters
@@ -125,22 +126,62 @@ module.exports = {
             },
           },
         ],
+        "camelcase": "off",
+        // TODO: These rules allow a lot of stuff and don't really enforce. If we want to apply our styleguide, we'd need to fix a lot of stuff
         "@typescript-eslint/naming-convention": [
+          "error",
           {
             selector: "default",
             format: ["camelCase"],
           },
-          { selector: "variable", format: ["camelCase", "UPPER_CASE"] },
           {
-            selector: "parameter",
-            format: ["camelCase"],
+            selector: "variable",
+            format: ["camelCase", "UPPER_CASE", "PascalCase"],
+            leadingUnderscore: "allowSingleOrDouble",
+            trailingUnderscore: "allowSingleOrDouble",
+          },
+          {
+            selector: "function",
+            format: ["camelCase", "PascalCase"],
             leadingUnderscore: "allow",
-            prefix: ["unstable_", ""],
+          },
+          {
+            selector: "parameter",
+            format: ["camelCase", "PascalCase", "snake_case"],
+            leadingUnderscore: "allowSingleOrDouble",
+          },
+          {
+            selector: "enumMember",
+            format: ["camelCase", "UPPER_CASE", "PascalCase"]
           },
           {
             selector: "typeLike",
             format: ["PascalCase"],
           },
+          {
+            selector: "typeAlias",
+            format: ["camelCase", "PascalCase"]
+          },
+          {
+            selector: "property",
+            format: ["PascalCase", "UPPER_CASE", "camelCase", "snake_case"],
+            leadingUnderscore: "allowSingleOrDouble",
+          },
+          {
+            selector: "objectLiteralProperty",
+            format: ["PascalCase", "UPPER_CASE", "camelCase", "snake_case"],
+            leadingUnderscore: "allowSingleOrDouble",
+            trailingUnderscore: "allowSingleOrDouble",
+          },
+          {
+            selector: "enum",
+            format: ["PascalCase", "UPPER_CASE"]
+          },
+          {
+            selector: "method",
+            format: ["PascalCase", "camelCase"],
+            leadingUnderscore: "allowSingleOrDouble",
+          },
           {
             selector: "interface",
             format: ["PascalCase"],
@@ -153,6 +194,7 @@ module.exports = {
         // mocking. At this point it's easier to have it off and just encourage
         // using top-level imports via code reviews.
         "@typescript-eslint/no-var-requires": "off",
+        "@typescript-eslint/no-extra-semi": "off",
         // This rule ensures that typescript types do not have semicolons
         // at the end of their lines, since our prettier setup is to have no semicolons
         // e.g.,
@@ -160,7 +202,6 @@ module.exports = {
         // -  baz: string;
         // +  baz: string
         // }
-        "@typescript-eslint/no-extra-semi": false,
         "@typescript-eslint/member-delimiter-style": [
           "error",
           {
diff --git a/packages/gatsby-link/index.d.ts b/packages/gatsby-link/index.d.ts
index e08b07f6b857c..74526f67856b5 100644
--- a/packages/gatsby-link/index.d.ts
+++ b/packages/gatsby-link/index.d.ts
@@ -1,7 +1,7 @@
 import * as React from "react"
 import { NavigateFn, LinkProps } from "@reach/router"
 
-// eslint-disable-next-line @typescript-eslint/interface-name-prefix
+// eslint-disable-next-line @typescript-eslint/naming-convention
 export interface GatsbyLinkProps<TState> extends LinkProps<TState> {
   /** A class to apply when this Link is active */
   activeClassName?: string
diff --git a/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.browser.tsx b/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.browser.tsx
index a2da1d65313a5..71a59493858e4 100644
--- a/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.browser.tsx
+++ b/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.browser.tsx
@@ -5,6 +5,7 @@ import * as hooks from "../hooks"
 
 type GlobalOverride = NodeJS.Global &
   typeof global.globalThis & {
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     GATSBY___IMAGE: boolean
     SERVER: boolean
   }
diff --git a/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.server.tsx b/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.server.tsx
index 18af1d422dd5e..ecb4db475f0e1 100644
--- a/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.server.tsx
+++ b/packages/gatsby-plugin-image/src/components/__tests__/gatsby-image.server.tsx
@@ -7,6 +7,7 @@ import { SourceProps } from "../picture"
 type GlobalOverride = NodeJS.Global &
   typeof global.globalThis & {
     SERVER: boolean | undefined
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     GATSBY___IMAGE: boolean | undefined
   }
 
diff --git a/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx b/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx
index f31269ed51c70..0814691197560 100644
--- a/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx
+++ b/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx
@@ -19,7 +19,7 @@ import { MainImageProps } from "./main-image"
 import { Layout } from "../image-utils"
 import { getSizer } from "./layout-wrapper"
 
-// eslint-disable-next-line @typescript-eslint/interface-name-prefix
+// eslint-disable-next-line @typescript-eslint/naming-convention
 export interface GatsbyImageProps
   extends Omit<
     ImgHTMLAttributes<HTMLImageElement>,
diff --git a/packages/gatsby-plugin-page-creator/src/__tests__/extract-query.ts b/packages/gatsby-plugin-page-creator/src/__tests__/extract-query.ts
index f0b823fcdf0b2..52f2782e07051 100644
--- a/packages/gatsby-plugin-page-creator/src/__tests__/extract-query.ts
+++ b/packages/gatsby-plugin-page-creator/src/__tests__/extract-query.ts
@@ -216,6 +216,7 @@ describe(`reverseLookupParams`, () => {
         compatiblePath(`/{Model.fields__name}.js`)
       )
     ).toEqual({
+      // eslint-disable-next-line @typescript-eslint/naming-convention
       fields__name: `foo`,
     })
     expect(
@@ -224,6 +225,7 @@ describe(`reverseLookupParams`, () => {
         compatiblePath(`/{_model.fields__name}.js`)
       )
     ).toEqual({
+      // eslint-disable-next-line @typescript-eslint/naming-convention
       fields__name: `foo`,
     })
   })
@@ -236,6 +238,7 @@ describe(`reverseLookupParams`, () => {
         compatiblePath(`/{Model.parent__(File)__relativePath}.js`)
       )
     ).toEqual({
+      // eslint-disable-next-line @typescript-eslint/naming-convention
       parent__relativePath: `foo`,
     })
     expect(
@@ -245,6 +248,7 @@ describe(`reverseLookupParams`, () => {
         compatiblePath(`/{model123.parent__(File)__relativePath}.js`)
       )
     ).toEqual({
+      // eslint-disable-next-line @typescript-eslint/naming-convention
       parent__relativePath: `foo`,
     })
   })
diff --git a/packages/gatsby/src/joi-schemas/joi.ts b/packages/gatsby/src/joi-schemas/joi.ts
index 3bc65d2ccbb28..e8a34df017e28 100644
--- a/packages/gatsby/src/joi-schemas/joi.ts
+++ b/packages/gatsby/src/joi-schemas/joi.ts
@@ -86,6 +86,7 @@ export const pageSchema: Joi.ObjectSchema<IGatsbyPage> = Joi.object()
     component: Joi.string().required(),
     componentChunkName: Joi.string().required(),
     context: Joi.object(),
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     pluginCreator___NODE: Joi.string(),
     pluginCreatorId: Joi.string(),
   })
diff --git a/packages/gatsby/src/redux/plugin-runner.ts b/packages/gatsby/src/redux/plugin-runner.ts
index 8db7b680f35ec..c650ac21c43cb 100644
--- a/packages/gatsby/src/redux/plugin-runner.ts
+++ b/packages/gatsby/src/redux/plugin-runner.ts
@@ -33,6 +33,7 @@ interface ICreatePageAction {
       id: string
     }
     updatedAt: number
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     pluginCreator___NODE: string
     pluginCreatorId: string
     componentPath: string
diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts
index f1219daed0a4e..36a5bfbf0d2be 100644
--- a/packages/gatsby/src/redux/types.ts
+++ b/packages/gatsby/src/redux/types.ts
@@ -33,6 +33,7 @@ export interface IGatsbyPage {
   isCreatedByStatefulCreatePages: boolean
   context: Record<string, unknown>
   updatedAt: number
+  // eslint-disable-next-line @typescript-eslint/naming-convention
   pluginCreator___NODE: Identifier
   pluginCreatorId: Identifier
   componentPath: SystemPath
diff --git a/packages/gatsby/src/schema/infer/__tests__/inference-metadata.ts b/packages/gatsby/src/schema/infer/__tests__/inference-metadata.ts
index e16e8ceca0dbd..de03708492ece 100644
--- a/packages/gatsby/src/schema/infer/__tests__/inference-metadata.ts
+++ b/packages/gatsby/src/schema/infer/__tests__/inference-metadata.ts
@@ -675,6 +675,7 @@ describe(`Get example value for type inference`, () => {
     })
   })
 
+  /* eslint-disable @typescript-eslint/naming-convention */
   describe(`Handles ___NODE foreign-key convenience relations`, () => {
     it(`infers single related node id as a simple string`, () => {
       const example = getExampleValueWithoutConflicts({
@@ -719,6 +720,7 @@ describe(`Get example value for type inference`, () => {
       expect(example.related___NODE).toEqual(INVALID_VALUE)
     })
   })
+  /* eslint-enable @typescript-eslint/naming-convention */
 
   describe(`Incremental example value building`, () => {
     const _nodes = [
@@ -907,6 +909,7 @@ describe(`Type conflicts`, () => {
   })
 
   it(`reports on mixed ___NODE fields`, () => {
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     const nodes = [{ related___NODE: `foo` }, { related___NODE: [`bar`] }]
 
     const conflicts = getExampleValueConflicts({
@@ -1045,7 +1048,9 @@ describe(`Type change detection`, () => {
     { object: { foo: `foo`, bar: `bar` } },
     { list: [`item`], bar: `bar` },
     { listOfObjects: [{ foo: `foo`, bar: `bar` }] },
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     { relatedNode___NODE: `foo` },
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     { relatedNodeList___NODE: [`foo`] },
   ]
 
@@ -1142,6 +1147,7 @@ describe(`Type change detection`, () => {
     expect(haveEqualFields(metadata, initialMetadata)).toEqual(true)
   })
 
+  /* eslint-disable @typescript-eslint/naming-convention */
   it(`detects on any change of the relatedNode field`, () => {
     // We do not know a type of the node being added hence consider and
     // add/delete to such fields as mutations
@@ -1179,6 +1185,7 @@ describe(`Type change detection`, () => {
     expect(metadata.dirty).toEqual(false)
     expect(haveEqualFields(metadata, initialMetadata)).toEqual(true)
   })
+  /* eslint-enable @typescript-eslint/naming-convention */
 
   it(`does not detect on symmetric add/delete`, () => {
     let metadata
diff --git a/packages/gatsby/src/utils/api-node-docs.ts b/packages/gatsby/src/utils/api-node-docs.ts
index f7d338b1c74d4..8d0b891500541 100644
--- a/packages/gatsby/src/utils/api-node-docs.ts
+++ b/packages/gatsby/src/utils/api-node-docs.ts
@@ -150,6 +150,7 @@ export const onCreateNode = true
  * @example
  * exports.unstable_shouldOnCreateNode = ({node}, pluginOptions) => node.internal.type === 'Image'
  */
+// eslint-disable-next-line @typescript-eslint/naming-convention
 export const unstable_shouldOnCreateNode = true
 
 /**
diff --git a/packages/gatsby/src/utils/fast-refresh-module.ts b/packages/gatsby/src/utils/fast-refresh-module.ts
index a4e0a8a16a75f..35dc4a5a2473c 100644
--- a/packages/gatsby/src/utils/fast-refresh-module.ts
+++ b/packages/gatsby/src/utils/fast-refresh-module.ts
@@ -8,7 +8,7 @@ type Event = [
 ]
 
 declare global {
-  // eslint-disable-next-line @typescript-eslint/interface-name-prefix
+  // eslint-disable-next-line @typescript-eslint/naming-convention
   interface Window {
     _gatsbyEvents: Array<Event> | { push: (event: Event) => void }
   }
diff --git a/packages/gatsby/src/utils/webpack/__tests__/corejs-resolver.ts b/packages/gatsby/src/utils/webpack/__tests__/corejs-resolver.ts
index 40792fff607cd..c9fd4b60566c0 100644
--- a/packages/gatsby/src/utils/webpack/__tests__/corejs-resolver.ts
+++ b/packages/gatsby/src/utils/webpack/__tests__/corejs-resolver.ts
@@ -32,6 +32,7 @@ describe(`CoreJSResolver`, () => {
   it(`should convert core-js@2 file to core-js@3`, async () => {
     const resolver = new CoreJSResolver()
 
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     const doResolve = jest.fn((_, request, __, ___, callback) =>
       callback(null, slash(request.request))
     )
@@ -48,6 +49,7 @@ describe(`CoreJSResolver`, () => {
   it(`should convert es6.regexp.replace to it's corejs@3 equivalent`, async () => {
     const resolver = new CoreJSResolver()
 
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     const doResolve = jest.fn((_, request, __, ___, callback) =>
       callback(null, slash(request.request))
     )