Install and Manage Extensions
@monospace/cli 0.2 and @monospace/extension-kit 0.3. Overview
Monospace is self-hosted. Installing an extension means placing its built directory in your instance's install location, the directory Engine scans for extensions. An instance is a running Monospace deployment. There is no install API, no upload in Studio, and no marketplace.
Installing, reloading, updating, and removing work the same way for every extension, whatever its entry types. Every installed extension is available to every workspace on the instance. What an entry type needs after installation is covered in its own section. For data connector extensions, see Manage Data Sources.
Choose the Install Location
Engine reads extensions from the directory in MONOSPACE_EXTENSIONS__INSTALL_LOCATION. The default is ./extensions, resolved against Engine's working directory.
| Variable | Default | Effect |
|---|---|---|
MONOSPACE_EXTENSIONS__INSTALL_LOCATION | ./extensions | Directory Engine scans for installed extensions |
MONOSPACE_EXTENSIONS__AUTO_RELOAD | false | Watches the install location and reloads changed extensions without a restart |
Each subdirectory of the install location that contains a manifest.json is one installed extension. The CLI names it <namespace>__<name> after the extension id, but Engine reads the id from the manifest, not the directory name:
extensions/
└── example__artic/
├── manifest.json
└── example/
└── artic-connector.js
| Rule | Behavior |
|---|---|
| Missing or unreadable install location | Engine starts with no extensions installed and logs that none were loaded |
| Subdirectory with an invalid manifest | Skipped with a warning. Other extensions still load |
| Two subdirectories with the same extension id | The first in sorted directory order loads; the other is skipped |
| Two extensions with the same entry id | The entry from the first extension in sorted directory order loads. The later extension loads without that entry, and Engine logs skipping provider declared in installed bundle |
| Symlinked subdirectory | Not loaded. Place a real directory in the install location |
See Extension Config and Manifest for the layout rules.
Run Monospace in Docker
The Monospace image runs Engine from /monospace, so the default install location inside the container is /monospace/extensions. The quick-start compose file mounts the named volume extensions_data there, which keeps installed extensions across restarts. To install extensions you build on this machine, replace that volume with a bind mount of a host directory.
Create the directory next to your docker-compose.yaml first:
mkdir extensions
Creating it yourself makes your user its owner, instead of leaving it to Docker. A CLI run without write access to the install location fails: with extension.install_dir_unusable when it can't inspect or create the install directory, and with extension.install_failed when copying the build into it fails.
In the monospace service, swap the named volume for the bind mount the quick-start file lists, and uncomment automatic reloading:
monospace:
volumes:
- keys_data:/keys:ro
- uploads_data:/monospace/uploads
# - extensions_data:/monospace/extensions
- ./extensions:/monospace/extensions
environment:
MONOSPACE_EXTENSIONS__AUTO_RELOAD: "true"
| Setting | Why |
|---|---|
./extensions:/monospace/extensions | Point monospace extension build --install-to at ./extensions on the host, and Engine sees the build in its install location |
| Readable files | The container runs as user 65532, so that user must be able to read every file and enter every directory (e.g., 644 files and 755 directories) |
MONOSPACE_EXTENSIONS__AUTO_RELOAD | Loads new and changed extensions without restarting the container |
Restart the stack with docker compose up -d to apply the change. On macOS, changes made on the host through a bind mount can miss the container. If a new install doesn't load, run docker compose restart monospace.
Reload Extensions Automatically
Engine scans the install location once at startup. With MONOSPACE_EXTENSIONS__AUTO_RELOAD set to true, it also watches the location and rescans once changed files have been quiet for 500 ms.
At startup, Engine logs watching installed bundles directory for changes when the watcher runs. The install location must exist when Engine starts. If it doesn't, Engine logs failed to watch installed bundles directory; bundle hot reloading is inactive, and only a restart picks up extensions.
The CLI's install summary ends with Restart the engine to load it, unless it runs with MONOSPACE_EXTENSIONS__AUTO_RELOAD=true. With automatic reloading on, no restart is needed, except after a data connector build that changes its query capabilities. See Update an Extension.
Install an Extension
Build the extension and install it in one step with --install-to, from the extension project's root:
npm run build -- --install-to ../monospace/extensions
pnpm build --install-to ../monospace/extensions
yarn build --install-to ../monospace/extensions
bun run build --install-to ../monospace/extensions
The build script is the one monospace extension create scaffolds; it runs monospace extension build. ../monospace/extensions is the install location on the host, here the directory mounted into the container. The CLI writes the build to <install-to>/<namespace>__<name>/ and replaces a previous install of the same extension whole. See Install a Build for the rules.
To install an extension someone else built, copy its directory (the one containing manifest.json) into the install location.
Check the Install
At startup, Engine logs loaded installed bundle with the extension id for each extension it loads. With automatic reloading on, it logs bundle installed when a new extension appears and bundle changed; restarting its data sources when an installed one changes. It logs skipping installed bundle with the reason when the manifest is invalid. These logs confirm the manifest and file layout; the extension's code first runs when it's used.
For data connectors, check that each entry loaded with List Installed Data Connectors, or in Studio as described in Find Extensions in Studio.
Find Extensions in Studio
Studio lists installed extensions with no setting to turn on. Each list shows an extension's name and id, then each of its entries, such as example/artic-connector marked Data Connector:
| Where | What it lists |
|---|---|
| Workspace Settings > Extensions | The extensions available to the workspace |
| Organization > Extensions in the settings dialog, opened from your avatar | Every extension installed in the organization |
Both pages are marked Preview, and each requires the extension read entitlement. Workspace Settings checks the workspace entitlement, which the built-in Studio Access policy includes. The settings dialog checks the organization entitlement. Data connectors also appear when you add a data source: Data Model > Add Source lists each one, marked Extension. See Add a Data Source in Studio.
If a new install is missing from these lists, Engine hasn't loaded it. See Check the Install.
Update an Extension
Install the new build over the old one. The CLI replaces the extension's directory whole. When you copy files by hand, replace the directory rather than merging into it.
With automatic reloading on, Engine picks up the new build once its files stop changing. Without automatic reloading, restart the instance. If the new build's manifest is invalid, Engine treats the extension as removed; see Install Directory Layout.
For data connectors, an update can require changes to existing data sources. With automatic reloading on, a build that changes an entry's query capabilities deactivates the entry's existing data sources until a restart or a workspace rebuild. See Update Data Sources After an Extension Update.
Remove an Extension
Delete the extension's directory from the install location. Without automatic reloading, restart the instance so Engine drops it from the installed extensions.
For data connectors, delete the data sources that use the extension first. See Before You Remove an Extension.
Limits of Self-Hosted Installs
| Not available | Instead |
|---|---|
| Install API or Studio upload | Place the built directory in the install location |
| Marketplace or registry | Distribute the built directory yourself |
| Two versions of one extension side by side | One directory per extension id. A second directory with the same id is skipped |
| Per-workspace installs | Every extension in the install location is available to every workspace |
See Also
- Data Connector Quickstart: build, install, and query a first data connector
- Manage Data Sources: create, update, and delete the data sources that use a data connector
- CLI:
--install-to,--watch, and the CLI's error codes - Environment Variables: the extensions settings
Overview
Learn what extensions are, what you can build with them today, and how an extension goes from code to a running capability in your instance.
Overview
Understand how data connector extensions serve live queries, what their operations contract promises, and whether your external data source fits.