diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js
index 297e9fa1e5c..69f02b4ab50 100644
--- a/editors/code/.eslintrc.js
+++ b/editors/code/.eslintrc.js
@@ -33,5 +33,14 @@ module.exports = {
         "@typescript-eslint/semi": ["error", "always"],
         "@typescript-eslint/no-unnecessary-type-assertion": "error",
         "@typescript-eslint/no-floating-promises": "error",
+
+        "@typescript-eslint/consistent-type-imports": [
+            "error",
+            {
+                prefer: "type-imports",
+                fixStyle: "inline-type-imports",
+            },
+        ],
+        "@typescript-eslint/no-import-type-side-effects": "error",
     },
 };
diff --git a/editors/code/src/ast_inspector.ts b/editors/code/src/ast_inspector.ts
index fa963d8eb99..2ebfd564ca3 100644
--- a/editors/code/src/ast_inspector.ts
+++ b/editors/code/src/ast_inspector.ts
@@ -1,7 +1,7 @@
 import * as vscode from "vscode";
 
-import { Ctx, Disposable } from "./ctx";
-import { RustEditor, isRustEditor } from "./util";
+import type { Ctx, Disposable } from "./ctx";
+import { type RustEditor, isRustEditor } from "./util";
 import { unwrapUndefinable } from "./undefinable";
 
 // FIXME: consider implementing this via the Tree View API?
diff --git a/editors/code/src/bootstrap.ts b/editors/code/src/bootstrap.ts
index 7b831a8a695..85668a23f37 100644
--- a/editors/code/src/bootstrap.ts
+++ b/editors/code/src/bootstrap.ts
@@ -1,8 +1,8 @@
 import * as vscode from "vscode";
 import * as os from "os";
-import { Config } from "./config";
+import type { Config } from "./config";
 import { log, isValidExecutable } from "./util";
-import { PersistentState } from "./persistent_state";
+import type { PersistentState } from "./persistent_state";
 import { exec } from "child_process";
 
 export async function bootstrap(
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 7b151c804af..35a114fb04d 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -6,7 +6,7 @@ import * as Is from "vscode-languageclient/lib/common/utils/is";
 import { assert } from "./util";
 import * as diagnostics from "./diagnostics";
 import { WorkspaceEdit } from "vscode";
-import { Config, prepareVSCodeConfig } from "./config";
+import { type Config, prepareVSCodeConfig } from "./config";
 import { randomUUID } from "crypto";
 import { sep as pathSeparator } from "path";
 import { unwrapUndefinable } from "./undefinable";
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 94ec5e99c6a..1289fa2ac73 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -3,23 +3,23 @@ import * as lc from "vscode-languageclient";
 import * as ra from "./lsp_ext";
 import * as path from "path";
 
-import { Ctx, Cmd, CtxInit, discoverWorkspace } from "./ctx";
+import { type Ctx, type Cmd, type CtxInit, discoverWorkspace } from "./ctx";
 import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
 import { spawnSync } from "child_process";
-import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
+import { type RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
 import { AstInspector } from "./ast_inspector";
 import {
     isRustDocument,
     isCargoTomlDocument,
     sleep,
     isRustEditor,
-    RustEditor,
-    RustDocument,
+    type RustEditor,
+    type RustDocument,
 } from "./util";
 import { startDebugSession, makeDebugConfig } from "./debug";
-import { LanguageClient } from "vscode-languageclient/node";
+import type { LanguageClient } from "vscode-languageclient/node";
 import { LINKED_COMMANDS } from "./client";
-import { DependencyId } from "./dependencies_provider";
+import type { DependencyId } from "./dependencies_provider";
 import { unwrapUndefinable } from "./undefinable";
 
 export * from "./ast_inspector";
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 7f4efebb2af..7dbc4bdd47b 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -2,7 +2,7 @@ import * as Is from "vscode-languageclient/lib/common/utils/is";
 import * as os from "os";
 import * as path from "path";
 import * as vscode from "vscode";
-import { Env } from "./client";
+import type { Env } from "./client";
 import { log } from "./util";
 import { expectNotUndefined, unwrapUndefinable } from "./undefinable";
 
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index a72b5391ff1..1ae0c96c6e7 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -1,5 +1,5 @@
 import * as vscode from "vscode";
-import * as lc from "vscode-languageclient/node";
+import type * as lc from "vscode-languageclient/node";
 import * as ra from "./lsp_ext";
 import * as path from "path";
 
@@ -12,19 +12,19 @@ import {
     isRustEditor,
     LazyOutputChannel,
     log,
-    RustEditor,
+    type RustEditor,
 } from "./util";
-import { ServerStatusParams } from "./lsp_ext";
+import type { ServerStatusParams } from "./lsp_ext";
 import {
-    Dependency,
-    DependencyFile,
+    type Dependency,
+    type DependencyFile,
     RustDependenciesProvider,
-    DependencyId,
+    type DependencyId,
 } from "./dependencies_provider";
 import { execRevealDependency } from "./commands";
 import { PersistentState } from "./persistent_state";
 import { bootstrap } from "./bootstrap";
-import { ExecOptions } from "child_process";
+import type { ExecOptions } from "child_process";
 
 // We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if
 // only those are in use. We use "Empty" to represent these scenarios
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index 29758feafe4..484f547230f 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -1,10 +1,10 @@
 import * as os from "os";
 import * as vscode from "vscode";
 import * as path from "path";
-import * as ra from "./lsp_ext";
+import type * as ra from "./lsp_ext";
 
 import { Cargo, getRustcId, getSysroot } from "./toolchain";
-import { Ctx } from "./ctx";
+import type { Ctx } from "./ctx";
 import { prepareEnv } from "./run";
 import { unwrapUndefinable } from "./undefinable";
 
diff --git a/editors/code/src/dependencies_provider.ts b/editors/code/src/dependencies_provider.ts
index 51ba11ecc92..98d6d7001a6 100644
--- a/editors/code/src/dependencies_provider.ts
+++ b/editors/code/src/dependencies_provider.ts
@@ -1,9 +1,9 @@
 import * as vscode from "vscode";
 import * as fspath from "path";
 import * as fs from "fs";
-import { CtxInit } from "./ctx";
+import type { CtxInit } from "./ctx";
 import * as ra from "./lsp_ext";
-import { FetchDependencyListResult } from "./lsp_ext";
+import type { FetchDependencyListResult } from "./lsp_ext";
 import { unwrapUndefinable } from "./undefinable";
 
 export class RustDependenciesProvider
diff --git a/editors/code/src/diagnostics.ts b/editors/code/src/diagnostics.ts
index a7e0845a278..e573f5a63f5 100644
--- a/editors/code/src/diagnostics.ts
+++ b/editors/code/src/diagnostics.ts
@@ -1,7 +1,13 @@
 import * as anser from "anser";
 import * as vscode from "vscode";
-import { ProviderResult, Range, TextEditorDecorationType, ThemeColor, window } from "vscode";
-import { Ctx } from "./ctx";
+import {
+    type ProviderResult,
+    Range,
+    type TextEditorDecorationType,
+    ThemeColor,
+    window,
+} from "vscode";
+import type { Ctx } from "./ctx";
 import { unwrapUndefinable } from "./undefinable";
 
 export const URI_SCHEME = "rust-analyzer-diagnostics-view";
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 64aea03394a..1121951c07f 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
 import * as lc from "vscode-languageclient/node";
 
 import * as commands from "./commands";
-import { CommandFactory, Ctx, fetchWorkspace } from "./ctx";
+import { type CommandFactory, Ctx, fetchWorkspace } from "./ctx";
 import * as diagnostics from "./diagnostics";
 import { activateTaskProvider } from "./tasks";
 import { setContextValue } from "./util";
diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts
index 8964a78dc32..cebd16a3c90 100644
--- a/editors/code/src/persistent_state.ts
+++ b/editors/code/src/persistent_state.ts
@@ -1,4 +1,4 @@
-import * as vscode from "vscode";
+import type * as vscode from "vscode";
 import { log } from "./util";
 
 export class PersistentState {
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts
index c20a5487b77..8ec569b6036 100644
--- a/editors/code/src/run.ts
+++ b/editors/code/src/run.ts
@@ -1,11 +1,11 @@
 import * as vscode from "vscode";
-import * as lc from "vscode-languageclient";
+import type * as lc from "vscode-languageclient";
 import * as ra from "./lsp_ext";
 import * as tasks from "./tasks";
 
-import { CtxInit } from "./ctx";
+import type { CtxInit } from "./ctx";
 import { makeDebugConfig } from "./debug";
-import { Config, RunnableEnvCfg } from "./config";
+import type { Config, RunnableEnvCfg } from "./config";
 import { unwrapUndefinable } from "./undefinable";
 
 const quickPickButtons = [
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts
index 5199508c822..f451e738d5d 100644
--- a/editors/code/src/tasks.ts
+++ b/editors/code/src/tasks.ts
@@ -1,6 +1,6 @@
 import * as vscode from "vscode";
 import * as toolchain from "./toolchain";
-import { Config } from "./config";
+import type { Config } from "./config";
 import { log } from "./util";
 import { unwrapUndefinable } from "./undefinable";
 
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index b6240234aa6..64f4582770b 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,6 @@
 import * as vscode from "vscode";
 import { strict as nativeAssert } from "assert";
-import { exec, ExecOptions, spawnSync } from "child_process";
+import { exec, type ExecOptions, spawnSync } from "child_process";
 import { inspect } from "util";
 
 export function assert(condition: boolean, explanation: string): asserts condition {
diff --git a/editors/code/tests/unit/launch_config.test.ts b/editors/code/tests/unit/launch_config.test.ts
index 0531e064d2d..eeb8608a42d 100644
--- a/editors/code/tests/unit/launch_config.test.ts
+++ b/editors/code/tests/unit/launch_config.test.ts
@@ -1,6 +1,6 @@
 import * as assert from "assert";
 import { Cargo } from "../../src/toolchain";
-import { Context } from ".";
+import type { Context } from ".";
 
 export async function getTests(ctx: Context) {
     await ctx.suite("Launch configuration/Lens", (suite) => {
diff --git a/editors/code/tests/unit/runnable_env.test.ts b/editors/code/tests/unit/runnable_env.test.ts
index b7d59e399dd..b1407ce0193 100644
--- a/editors/code/tests/unit/runnable_env.test.ts
+++ b/editors/code/tests/unit/runnable_env.test.ts
@@ -1,8 +1,8 @@
 import * as assert from "assert";
 import { prepareEnv } from "../../src/run";
-import { RunnableEnvCfg } from "../../src/config";
-import { Context } from ".";
-import * as ra from "../../src/lsp_ext";
+import type { RunnableEnvCfg } from "../../src/config";
+import type { Context } from ".";
+import type * as ra from "../../src/lsp_ext";
 
 function makeRunnable(label: string): ra.Runnable {
     return {
diff --git a/editors/code/tests/unit/settings.test.ts b/editors/code/tests/unit/settings.test.ts
index f171f5f74f3..bafb9569a1c 100644
--- a/editors/code/tests/unit/settings.test.ts
+++ b/editors/code/tests/unit/settings.test.ts
@@ -1,5 +1,5 @@
 import * as assert from "assert";
-import { Context } from ".";
+import type { Context } from ".";
 import { substituteVariablesInEnv } from "../../src/config";
 
 export async function getTests(ctx: Context) {