Migration to v4
startSubprocess() API Changes
The subprocess system has been migrated from execa to tinyexec.
SubprocessOptions no longer extends ExecaOptions
Previously, SubprocessOptions extended ExecaOptions from execa, allowing you to pass any execa option directly. It now has its own interface:
interface SubprocessOptions {
command: string
args?: string[]
cwd?: string
env?: Record<string, string | undefined>
nodeOptions?: SpawnOptions // from 'node:child_process'
}
Common fields like cwd and env are still available as top-level options. Other execa-specific options should be migrated to nodeOptions (Node.js SpawnOptions):
startSubprocess({
command: 'my-command',
args: ['--flag'],
cwd: '/some/path',
- stdio: 'pipe',
+ nodeOptions: {
+ stdio: 'pipe',
+ },
})
startSubprocess() is deprecated {#ndt_dep_0004}
startSubprocess() is soft-deprecated in favour of the Vite DevTools terminals
host, used from the onDevtoolsReady hook.
It still works as a shim, but emits the NDT_DEP_0004 deprecation diagnostic.
- import { startSubprocess } from '@nuxt/devtools-kit'
+ import { onDevtoolsReady } from '@nuxt/devtools-kit'
- const subprocess = startSubprocess(
- { command: 'vite', args: ['build', '--watch'] },
- { id: 'my-module:build', name: 'Build', icon: 'ph:terminal-duotone' },
- )
+ onDevtoolsReady(async (ctx) => {
+ const session = await ctx.terminals.startChildProcess(
+ { command: 'vite', args: ['build', '--watch'], cwd: process.cwd() },
+ { id: 'my-module:build', title: 'Build', icon: 'ph:terminal-duotone' },
+ )
+ })
The terminals host session exposes terminate(), restart(),
getChildProcess(), and getResult() — a tinyexec-style awaitable handle that
resolves to { stdout, stderr, exitCode } — so the startSubprocess().getResult()
ergonomics carry over:
onDevtoolsReady(async (ctx) => {
const session = await ctx.terminals.startChildProcess(
{ command: 'npm', args: ['install'] },
{ id: 'my-module:install', title: 'Install' },
)
const { exitCode, stderr } = await session.getResult()
if (exitCode !== 0)
console.error(stderr)
})
getProcess() is deprecated {#ndt_dep_0001}
The return value of startSubprocess() now also provides getResult(); use it instead of the deprecated getProcess() method.
getProcess()still works but emits theNDT_DEP_0001deprecation diagnostic and returnsChildProcess | undefined(wasExecaChildProcess<string>)getResult()returns a tinyexecResultobject with.kill(),.process,.pipe(), and more
const subprocess = startSubprocess(/* ... */)
- const proc = subprocess.getProcess()
- proc.stdout.on('data', handler)
+ const result = subprocess.getResult()
+ result.process?.stdout?.on('data', handler)
extendServerRpc() is deprecated {#ndt_dep_0003}
extendServerRpc() is soft-deprecated in favour of the Vite DevTools RPC
registration, done from the onDevtoolsReady
hook. It still works as a shim, but emits the NDT_DEP_0003 deprecation
diagnostic.
- import { extendServerRpc } from '@nuxt/devtools-kit'
+ import { onDevtoolsReady } from '@nuxt/devtools-kit'
+ import { defineRpcFunction } from '@vitejs/devtools-kit'
- const rpc = extendServerRpc('my-module', {
- async getData() {
- return 'hello'
- },
- })
+ onDevtoolsReady((ctx) => {
+ ctx.rpc.register(defineRpcFunction({
+ name: 'my-module:get-data',
+ type: 'query',
+ setup: () => ({ handler: async () => 'hello' }),
+ }))
+ })
To broadcast to clients from the same context, use ctx.rpc.broadcast({ method, args, event }).
nuxt.devtools.rpc direct access is deprecated {#ndt_dep_0007}
Directly accessing nuxt.devtools.rpc.broadcast or nuxt.devtools.rpc.functions
is deprecated (NDT_DEP_0007). They still work as a shim, but you should use the
connected ctx.rpc (the devframe RpcFunctionsHost) from the
onDevtoolsReady hook instead:
- nuxt.devtools.rpc.broadcast.myEvent.asEvent(payload)
+ onDevtoolsReady((ctx) => {
+ ctx.rpc.broadcast({ method: 'myEvent', args: [payload], event: true })
+ })
- nuxt.devtools.rpc.functions.myFn = handler
+ onDevtoolsReady((ctx) => {
+ ctx.rpc.register({ name: 'myFn', handler })
+ })
addCustomTab() is deprecated {#ndt_dep_0005}
addCustomTab() is soft-deprecated in favour of registering a dock entry on the
Vite DevTools docks host, from the
onDevtoolsReady hook. It still works as a
shim, but emits the NDT_DEP_0005 deprecation diagnostic.
- import { addCustomTab } from '@nuxt/devtools-kit'
+ import { onDevtoolsReady } from '@nuxt/devtools-kit'
- addCustomTab({
- name: 'my-module',
- title: 'My Module',
- icon: 'carbon:apps',
- view: { type: 'iframe', src: '/url-to-your-module-view' },
- })
+ onDevtoolsReady((ctx) => {
+ ctx.docks.register({
+ id: 'my-module',
+ title: 'My Module',
+ icon: 'carbon:apps',
+ type: 'iframe',
+ url: '/url-to-your-module-view',
+ })
+ })
vnode views or tab categories. If you rely on those, keep using
addCustomTab() for now.refreshCustomTabs() is deprecated {#ndt_dep_0006}
refreshCustomTabs() is soft-deprecated (NDT_DEP_0006). With the docks host you
no longer re-run a hook to refresh — update the dock entry directly via the
handle returned by register() inside the
onDevtoolsReady hook:
onDevtoolsReady((ctx) => {
const entry = ctx.docks.register({ id: 'my-module', /* ... */ })
entry.update({ title: 'My Module (updated)' })
})
Global Install Support Removed
Nuxt DevTools no longer supports being installed globally.
- The
devtoolsGlobalNuxt config option (withprojectswhitelist) is no longer supported - The
-gflag is no longer used when installing/uninstalling@nuxt/devtoolsvia the DevTools UI - The
isGlobalInstallproperty has been removed fromNuxtDevtoolsInfo
@nuxt/devtools-wizard Package and nuxi devtools Removed
The @nuxt/devtools-wizard package, its CLI, and the nuxi devtools enable/disable subcommand have been removed. DevTools is shipped with Nuxt — to enable or disable it, update your nuxt.config.ts directly:
export default defineNuxtConfig({
devtools: { enabled: true }, // or false
})
runWizard RPC Removed
The runWizard server RPC function has been removed from ServerFunctions. The enablePages action is now available as a direct RPC function:
- await rpc.runWizard(token, 'enablePages')
+ await rpc.enablePages(token)
The WizardFunctions, WizardActions, and GetWizardArgs types have been removed from @nuxt/devtools-kit.
Vite DevTools Integration is Now Always Enabled
The viteDevTools module option has been removed. Nuxt DevTools now always integrates with Vite DevTools as a dock entry. The built-in floating panel has been removed — DevTools is accessed through the Vite DevTools panel instead.
export default defineNuxtConfig({
devtools: {
enabled: true,
- viteDevTools: true,
},
})
client.devtools Methods Now Control Vite DevTools
The client.devtools.open(), client.devtools.close(), and client.devtools.toggle() methods still work but now control the Vite DevTools panel:
open()opens the Vite DevTools panel and switches to the Nuxt DevTools dock entryclose()closes the Vite DevTools paneltoggle()toggles the Nuxt DevTools dock entry in the Vite DevTools panel
The Shift+Alt+D keyboard shortcut now toggles the Nuxt DevTools entry in the Vite DevTools panel.
client.devtools.popup Removed
The Picture-in-Picture popup feature (client.devtools.popup) has been removed. This was an experimental feature that required Chrome 111+.
showPanel and minimizePanelInactive Settings Removed
The showPanel and minimizePanelInactive UI settings have been removed from NuxtDevToolsOptions as the built-in floating panel no longer exists.