diff --git a/docs/guide/index.md b/docs/guide/index.md
index 60d73b27..a45503ce 100644
--- a/docs/guide/index.md
+++ b/docs/guide/index.md
@@ -101,25 +101,18 @@ export default defineConfig({
#### Projects without an HTML entry
-For apps where Vite doesn't serve the HTML (JS-only entries, backend integration, middleware mode), import the client injector from a browser entry instead. One entry per visibility mode — import whichever one you want:
-
-```ts twoslash
-// Normal: docks shown immediately
-// @ts-expect-error TODO: Remove when this entry has type declarations.
-import '@vitejs/devtools/client/inject'
-```
-
-```ts twoslash
-// Passive: docks hidden until Shift+Alt+D, then remembered
-// @ts-expect-error TODO: Remove when this entry has type declarations.
-import '@vitejs/devtools/client/inject-passive'
+For apps where Vite doesn't serve the HTML (JS-only entries, backend integration, middleware mode), load the client script that the dev server hosts at `/__devtools/embedded.js` from a browser entry instead:
+
+```ts [main.ts]
+if (import.meta.env.DEV) {
+ const script = document.createElement('script')
+ script.type = 'module'
+ script.src = `${new URL(import.meta.url).origin}/__devtools/embedded.js`
+ document.body.appendChild(script)
+}
```
-```ts twoslash
-// Hidden: docks hidden until Shift+Alt+D, every session
-// @ts-expect-error TODO: Remove when this entry has type declarations.
-import '@vitejs/devtools/client/inject-hidden'
-```
+The script is served by the Vite dev server, so its URL uses the dev server's origin. The visibility mode follows the `embeddedVisibility` option above.
See [Client Script & Context](/kit/client-context#client-script-not-injected) for how injection works and the full troubleshooting checklist.
diff --git a/docs/kit/client-context.md b/docs/kit/client-context.md
index 12e61bcc..4e7f3f76 100644
--- a/docs/kit/client-context.md
+++ b/docs/kit/client-context.md
@@ -8,7 +8,7 @@ In embedded mode, Vite DevTools injects a small **client script** into your app'
## The client script
-The client script is the browser entry of Vite DevTools (published as `@vitejs/devtools/client/inject`). When it runs in the host page it:
+The client script is the browser entry of Vite DevTools, served by the dev server at `/__devtools/embedded.js`. When it runs in the host page it:
1. Connects an RPC client to the DevTools server at `/__devtools/` (WebSocket in dev mode).
2. Builds the `DevToolsClientContext` — dock entries, panel state, commands, when-clauses — on top of that RPC client.
@@ -17,7 +17,7 @@ The client script is the browser entry of Vite DevTools (published as `@vitejs/d
### How injection works
-The `DevTools()` plugin injects the script through Vite's `transformIndexHtml` hook. During `vite dev`, every HTML page served by Vite receives a module script that imports the injection virtual module, which in turn loads the client entry. The plugin picks the entry from the project's resolved visibility: `@vitejs/devtools/client/inject` (docks shown immediately) by default, `@vitejs/devtools/client/inject-passive` (docks hidden until Shift+Alt+D, then remembered) for passive mode, or `@vitejs/devtools/client/inject-hidden` (revealed per session, never remembered) for hidden mode:
+The `DevTools()` plugin injects the script through Vite's `transformIndexHtml` hook. During `vite dev`, every HTML page served by Vite receives a small inline module script that appends a `