--- title: Development sidebar_position: 6 --- # Development This guide covers everything you need to know about developing extensions for Superset, from project structure to development workflow. ## Project Structure The [apache-superset-extensions-cli](https://github.com/apache/superset/tree/master/superset-extensions-cli) package provides a command-line interface (CLI) that streamlines the extension development workflow. It offers the following commands: ``` superset-extensions init: Generates the initial folder structure and scaffolds a new extension project. superset-extensions build: Builds extension assets. superset-extensions bundle: Packages the extension into a .supx file. superset-extensions dev: Automatically rebuilds the extension as files change. ``` When creating a new extension with `superset-extensions init`, the CLI generates a standardized folder structure: ``` dataset-references/ ├── extension.json ├── frontend/ │ ├── src/ │ ├── webpack.config.js │ ├── tsconfig.json │ └── package.json ├── backend/ │ ├── src/ │ │ └── superset_extensions/ │ │ └── dataset_references/ │ ├── tests/ │ ├── pyproject.toml │ └── requirements.txt ├── dist/ │ ├── manifest.json │ ├── frontend │ │ └── dist/ │ │ ├── remoteEntry.d7a9225d042e4ccb6354.js │ │ └── 900.038b20cdff6d49cfa8d9.js │ └── backend │ └── superset_extensions/ │ └── dataset_references/ │ ├── __init__.py │ ├── api.py │ └── entrypoint.py ├── dataset-references-1.0.0.supx └── README.md ``` **Note**: The extension ID (`dataset-references`) serves as the basis for all technical names: - Directory name: `dataset-references` (kebab-case) - Backend Python package: `dataset_references` (snake_case) - Frontend package name: `dataset-references` (kebab-case) - Module Federation name: `datasetReferences` (camelCase) The `extension.json` file serves as the declared metadata for the extension, containing the extension's name, version, author, description, and a list of capabilities. This file is essential for the host application to understand how to load and manage the extension. The `frontend` directory contains the source code for the frontend components of the extension, including React components, styles, and assets. The `webpack.config.js` file is used to configure Webpack for building the frontend code, while the `tsconfig.json` file defines the TypeScript configuration for the project. The `package.json` file specifies the dependencies and scripts for building and testing the frontend code. The `backend` directory contains the source code for the backend components of the extension, including Python modules, tests, and configuration files. The `pyproject.toml` file is used to define the Python package and its dependencies, while the `requirements.txt` file lists the required Python packages for the extension. The `src` folder contains the functional backend source files, `tests` directory contains unit tests for the backend code, ensuring that the extension behaves as expected and meets the defined requirements. The `dist` directory is built when running the `build` or `dev` command, and contains the files that will be included in the bundle. The `manifest.json` file contains critical metadata about the extension, including the majority of the contents of the `extension.json` file, but also other build-time information, like the name of the built Webpack Module Federation remote entry file. The files in the `dist` directory will be zipped into the final `.supx` file. Although this file is technically a zip archive, the `.supx` extension makes it clear that it is a Superset extension package and follows a specific file layout. This packaged file can be distributed and installed in Superset instances. The `README.md` file provides documentation and instructions for using the extension, including how to install, configure, and use its functionality. ## Extension Metadata The `extension.json` file contains all metadata necessary for the host application to understand and manage the extension: ```json { "id": "dataset-references", "name": "Dataset References", "version": "1.0.0", "frontend": { "contributions": { "views": { "sqllab": { "panels": [ { "id": "dataset-references.main", "name": "Dataset References" } ] } } }, "moduleFederation": { "exposes": ["./index"], "name": "datasetReferences" } }, "backend": { "entryPoints": ["superset_extensions.dataset_references.entrypoint"], "files": ["backend/src/superset_extensions/dataset_references/**/*.py"] } } ``` The `contributions` section declares how the extension extends Superset's functionality through views, commands, menus, and other contribution types. The `backend` section specifies entry points and files to include in the bundle. ## Interacting with the Host Extensions interact with Superset through well-defined, versioned APIs provided by the `@apache-superset/core` (frontend) and `apache-superset-core` (backend) packages. These APIs are designed to be stable, discoverable, and consistent for both built-in and external extensions. **Note**: The `superset_core.api` module provides abstract classes that are replaced with concrete implementations via dependency injection when Superset initializes. This allows extensions to use the same interfaces as the host application. ### Frontend APIs The frontend extension APIs (via `@apache-superset/core`) are organized into logical namespaces such as `authentication`, `commands`, `extensions`, `sqlLab`, and others. Each namespace groups related functionality, making it easy for extension authors to discover and use the APIs relevant to their needs. For example, the `sqlLab` namespace provides events and methods specific to SQL Lab, allowing extensions to react to user actions and interact with the SQL Lab environment: ```typescript export const getCurrentTab: () => Tab | undefined; export const getDatabases: () => Database[]; export const getTabs: () => Tab[]; export const onDidChangeActivePanel: Event; export const onDidChangeTabTitle: Event; export const onDidQueryRun: Event; export const onDidQueryStop: Event; ``` The following code demonstrates more examples of the existing frontend APIs: ```typescript import { core, commands, sqlLab, authentication, Button } from '@apache-superset/core'; import MyPanel from './MyPanel'; export function activate(context) { // Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code const panelDisposable = core.registerView('my_extension.panel',