Getting started

While Studio offers a suite of built-in panels for robotics data visualization and debugging, many users have domain-specific needs that our out-of-the-box offering does not address.

Foxglove Studio's extensions API provides an interface to extending Studio to better support your custom workflows – whether it's by creating a custom panel or a message converter.

Once you've developed and installed your extension, you can open the Studio sidebar's Extensions tab to display all available and installed extensions.

Custom panels

Custom panel extensions allow you to build an entire panel. Custom panels can subscribe to messages on various topics, advertise and publish, and display the message information in whatever form is most relevant for your workflow.

Custom panels are ideal when your visualization or interaction needs are bespoke and not easily solved via one of the built-in panels.

Additional resources

Message converters

Message converter extensions allow you to convert messages from one schema to another. By transforming your custom messages to adhere to a Foxglove-supported schema, you can inspect them using Foxglove Studio's built-in visualization features.

For example, an extension could convert your custom GPS message into a foxglove.LocationFix message to be displayed within the Map panel.

Additional resources

Writing an extension

You can write extensions in JavaScript or Typescript and package them into .foxe files. You can distribute these files privately to your Foxglove organization or publicly via our marketplace. A single extension can include multiple panels or converters.

Foxglove provides a set of starter templates and commands in the create-foxglove-extension package to simplify authoring an extension.


To set up your extension project, navigate to the directory where you'll want your source code to live and run the following command in a Terminal window:

$ npm init [email protected] my-extension-name

This will set up an extension directory structure. The entrypoint of your extension is the index.ts file.

The entrypoint script MUST export a single activate function which accepts a single ExtensionContext argument.

export function activate(extensionContext: ExtensionContext) {
  // your extension code will decide which methods to call on the extensionContext
  // Here's an example which registers a new panel:
  extensionContext.registerPanel({ name: "example-panel", initPanel: initExamplePanel });

API reference