Administrators can install sandboxed plugins from the plugin registry or register npm packages in astro.config.mjs. Config-based plugins can run in the sandbox or in the site process.
Prepare for admin installs
Registry installs require:
- An administrator account with the
plugins:managepermission. - Configured storage for downloaded plugin bundles.
- An available sandbox runner.
On Cloudflare Workers, use sandbox() from @emdash-cms/cloudflare:
import { sandbox } from "@emdash-cms/cloudflare";
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: sandbox(),
experimental: {
registry: "https://registry.emdashcms.com",
},
}),
],
});
The Cloudflare runner uses Worker Loader to create a separate Worker for each plugin. It requires the Workers Paid plan and a worker_loaders binding named LOADER. Sandboxed plugins reach content, media, storage, network, and email APIs through PluginBridge, so the site’s Worker entry point must export that class.
The *-cloudflare templates export PluginBridge but leave the Worker Loader binding commented out, so new projects can deploy on the Workers free plan. Enable sandboxed plugins during scaffolding or follow the Cloudflare sandbox setup to add the binding later. The sandbox() helper reads the effective Wrangler config at build time. Without LOADER, registry browsing remains available, but config-managed sandboxed plugins do not load and install or update requests return SANDBOX_NOT_AVAILABLE.
On Node.js, install the runner and its workerd peer dependency:
npm install @emdash-cms/sandbox-workerd workerd
The workerd process runs the plugin code separately from the Node.js server. Select the runner in the EmDash integration:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox",
experimental: {
registry: "https://registry.emdashcms.com",
},
}),
],
});
See Plugin sandbox for development setup, runtime requirements, resource limits, and unavailable-runner errors on both platforms.
Install from the registry
- Open Registry in the admin panel.
- Search for a plugin and open its detail page.
- Select a release and review its publisher, metadata, requested permissions, and verification status.
- Select Install.
- Review the verified release identifiers and permissions in the consent dialog, then confirm.
EmDash verifies the publisher’s current signed records and checks the downloaded bundle before loading it through the sandbox runner. The plugin appears under Plugins, where you can disable or configure it. See The plugin registry for the complete verification and trust model.
Review permissions
The consent dialog shows every permission declared by the plugin. Common permissions include:
| Permission | Access granted |
|---|---|
content:read | Read site content |
content:write | Create, update, and delete content |
media:read | Read media records and files |
media:write | Upload, replace, and delete media |
network:request | Send requests to the plugin’s allowed host list |
The dialog also identifies plugin routes exposed as Model Context Protocol (MCP) tools when a plugin declares them. See Capabilities and security for the complete permission model.
Update a plugin
- Open Plugins in the admin panel.
- Select Check for updates.
- Select Update on a registry plugin with an available release.
- Review the consent dialog, then confirm the update.
Registry updates require another confirmation when they add permissions or MCP tools, or when a route changes from authenticated to public. EmDash leaves the installed version in place until you approve the change.
Uninstall a plugin
- Open Plugins in the admin panel and expand the installed plugin.
- Select Uninstall.
- Select Also delete plugin storage data only if you do not need the plugin’s stored data for a later reinstall.
- Confirm the uninstall.
EmDash removes the installed bundle and stops loading the plugin. Plugin storage data remains by default.
Install from npm
Native plugins and config-managed sandboxed plugins install as npm dependencies. Follow the package’s instructions to choose plugins: [] or sandboxed: [].
The following example registers the native Field Kit plugin:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";
export default defineConfig({
integrations: [
emdash({
plugins: [fieldKitPlugin()],
}),
],
});
Config-managed plugins change when you update the npm dependency and deploy the site. They cannot be installed or removed from the admin panel.
Choose an install method
| Registry | npm with sandboxed: [] | npm with plugins: [] | |
|---|---|---|---|
| Install and update | Admin panel | Dependency change and deploy | Dependency change and deploy |
| Execution | Configured sandbox runner | Configured sandbox runner | Site process |
| Access to EmDash | Only declared plugin APIs | Only declared plugin APIs | Declared plugin APIs plus direct process access |
Node.js APIs and direct fetch() | Unavailable | Unavailable | Available |
| React admin components | Unavailable | Unavailable | Available |
| Portable Text renderers | Unavailable | Unavailable | Available |
Use a native plugin when it needs React admin components, Portable Text renderers, page fragments, or direct access to the site process. Use a sandboxed plugin when it can work through the declared plugin APIs.