Skip to main content
Glama
create-devtools-plugins.md4.99 kB
--- title: Create a dev tools plugin description: Learn how to create a dev tools plugin to enhance your development experience. --- > **Tip**: Check out the [Expo DevTools Plugins](https://github.com/expo/dev-plugins) for complete examples. You can create a dev tools plugin, whether that's for inspecting aspects of a common framework or library or something specific to your custom code. This guide will walk you through creating a dev tools plugin. ## What is a dev tools plugin? A dev tools plugin runs in your web browser in your local development environment and connects to your Expo app. A plugin consists of three key elements: - An Expo app to display the dev tools web user interface. - An **expo-module.config.json** for Expo CLI recognition. - Calls to `expo/devtools` API for the app to communicate back and forth with the dev tool's web interface. Plugins can be distributed on npm or included inside your app's monorepo. They typically export a single hook that can be used in your app's root component to initiate two-way communication with the web interface when your app is running in debug mode. ## Create a plugin ### Create a new plugin project `create-dev-plugin` will set up a new plugin project for you. Run the following command to create a new plugin project: `create-dev-plugin` will prompt you for the name of your plugin, a description, and the name of the hook that will be used by consumers of your plugin. The plugin project will contain the following directories: - **src** - this exports the hook that will be used inside the consuming app to connect it to the plugin. - **webui** - this contains the web user interface for the plugin. ### Customize a plugin's functionality The template includes a simple example of sending and receiving messages between the plugin and the app. `useDevToolsPluginClient`, imported from `expo/devtools`, provides functionality for sending and receiving messages between the plugin and the app. The client object returned by `useDevToolsPluginClient` includes: <PaddedAPIBox header="addMessageListener"> Listens for a message matching the typed string and invokes the callback with the message data. ```jsx const client = useDevToolsPluginClient('my-devtools-plugin'); client.addMessageListener('ping', data => { alert(`Received ping from ${data.from}`); }); ``` </PaddedAPIBox> <PaddedAPIBox header="sendMessage"> Listens for a message matching the typed string and invokes the callback with the message data. ```jsx const client = useDevToolsPluginClient('my-devtools-plugin'); client?.sendMessage('ping', { from: 'web' }); ``` </PaddedAPIBox> Edit the Expo app inside the **webui** directory to customize the user interface that displays diagnostic information from your app or triggers test scenarios: ```tsx webui/App.tsx const client = useDevToolsPluginClient('my-devtools-plugin'); useEffect(() => { const subscriptions: EventSubscription[] = []; subscriptions.push( client?.addMessageListener('ping', data => { alert(`Received ping from ${data.from}`); }) ); return () => { for (const subscription of subscriptions) { subscription?.remove(); } }; }, [client]); } ``` Edit the hook in the **src** directory to customize what diagnostic information is sent to the plugin or how the app should respond to any messages from the web user interface: ```tsx src/useMyDevToolsPlugin.ts const client = useDevToolsPluginClient('my-devtools-plugin'); const sendPing = () => { client?.sendMessage('ping', { from: 'app' }); }; return { sendPing, }; } ``` If you update the hook to return functions that will be called by the app, you will also need to update **src/index.ts** so it exports no-op functions when the app is not running in debug mode: ```diff src/index.ts if (process.env.NODE_ENV !== 'production') { useMyDevToolsPlugin = require('./useMyDevToolsPlugin').useMyDevToolsPlugin; } else { useMyDevToolsPlugin = () => ({ + sendPing: () => {}, }); } ``` ## Test a plugin Since the plugin web UI is an Expo app, you can test it just like you would any other Expo app, with `npx expo start`, except that you will run it in the browser only. The template includes a convenience command to run the plugin in local development mode: ## Build a plugin for distribution To prepare your plugin for distribution or use within your monorepo, you will need to build the plugin with the following command: This command will build the hook code into the **build** directory, and the web user interface into the **dist** directory. ## Use the plugin Import the plugin's hook into your app's root component and call it to connect your app to the plugin: ```jsx App.js const { sendPing } = useMyDevToolsPlugin(); return ( <View style={styles.container}> <Button title="Ping" onPress={() => { sendPing(); }} /> </View> ); } ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaksm/expo-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server