--- 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 the metadata necessary for the host application to identify and load the extension. Backend contributions (entry points and files) are declared here. Frontend contributions are registered directly in code from `frontend/src/index.tsx`. ```json { "publisher": "my-org", "name": "dataset-references", "displayName": "Dataset References", "version": "1.0.0", "license": "Apache-2.0", "backend": { "entryPoints": ["superset_extensions.dataset_references.entrypoint"], "files": ["backend/src/superset_extensions/dataset_references/**/*.py"] }, "permissions": [] } ``` The `backend` section specifies Python entry points to load eagerly when the extension starts, and glob patterns for source 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 React from 'react'; import { views, commands, sqlLab, authentication, Button } from '@apache-superset/core'; import MyPanel from './MyPanel'; // Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code views.registerView( { id: 'my-extension.panel', name: 'My Panel' }, 'sqllab.panels', () =>