Using React DevTools with Tauri v2 and Vite
(updated ) Eiko WagenknechtWhile working on a Tauri v2 app, I wanted to use the React DevTools to inspect the component tree and state of my React app. Two things are needed to make this work:
- You must run the standalone React DevTools app.
- The React DevTools script must be included in your HTML, so the app connects to the DevTools.
I’ll show three different approaches to include the React DevTools script in your Tauri app, starting from a simple direct script inclusion and ending with a Vite plugin that automatically injects the script only during development.
Table of Contents
- Installing the standalone React DevTools app
- Calling the React DevTools from your Tauri app
- Better: Vite plugin for automatic script injection
Installing the standalone React DevTools app
When using Tauri, you can not use the React DevTools browser extension, as Tauri apps run outside the browser context. Instead, you need to install the standalone React DevTools app.
To do so, add this to your package.json
:
{
"scripts": {
"devtools": "react-devtools"
},
"devDependencies": {
"react-devtools": "6.1.5"
}
}
Then run npm install
, yarn install
or pnpm install
to install the package.
After that, you can start the React DevTools app by running the devtools
script, for example:
pnpm run devtools
Calling the React DevTools from your Tauri app
There are several ways to include the React DevTools script in your Tauri app. Let’s start from the most basic approach and work our way up to a more elegant solution.
Simple: Direct script inclusion
You might start out by including the React DevTools script directly in your HTML file:
<script src="http://localhost:8097"></script>
This has some downsides, though:
- There is no way to conditionally include the script based on the environment.
- The script tag remains in your HTML even in production (though it won’t do anything there).
- It mixes development tooling with application code.
Not working: Conditional module import
Another approach is to conditionally import the React DevTools module:
// env.ts
export const include_devtools: boolean =
import.meta.env.VITE_INCLUDE_DEVTOOLS === "true";
<!-- index.html -->
<head>
<script type="module">
import { include_devtools } from "@/env.ts";
if (include_devtools) {
console.log("Including React devtools");
var script = document.createElement("script");
script.src = "http://localhost:8097";
document.head.appendChild(script);
}
</script>
</head>
This is supposed to only include the script tag in development mode. But is has downsides as well:
- Most importantly, it won’t work with Tauri v2 because the script loads too late to properly instrument React.
This results in the React DevTools not showing the component tree or state of your app and showing a message “Loading React Element Tree…” instead.
When you inspect the console, you see a
hook.sub is not a function
error. - The module script might not be processed correctly by your bundler.
- It requires managing environment variables.
- Still mixes development tooling with application code.
Better: Vite plugin for automatic script injection
So to fix this, we can instead create a simple Vite plugin that automatically injects the DevTools script only during development. This works perfectly with Tauri’s development setup.
To do so, just add the following plugin to your vite.config.ts
:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import type { PluginOption } from "vite";
const reactDevTools = (): PluginOption => {
return {
name: "react-devtools",
apply: "serve", // Only apply this plugin during development
transformIndexHtml(html) {
return {
html,
tags: [
{
tag: "script",
attrs: {
src: "http://localhost:8097",
},
injectTo: "head",
},
],
};
},
};
};
export default defineConfig({
plugins: [react(), reactDevTools()],
});
The plugin uses Vite’s transformIndexHtml
hook to modify your HTML during build.
apply: 'serve'
ensures the plugin only runs during development.
It injects the DevTools script tag into the <head>
of your document, so the script loads before your React application starts.
This is better than the previous approaches because:
- The DevTools script is only included during development.
- It doesn’t require any manual intervention.
- It doesn’t mix development tooling with application code.
- It works perfectly with Tauri v2.
- It doesn’t require managing environment variables.
- It works regardless of your bundler.
No Comments? No Problem.
This blog doesn't support comments, but your thoughts and questions are always welcome. Reach out through the contact details at the bottom of the page.
Support Me
If you found this page helpful and want to say thanks, you can support me here.