EmDash plugins are built on one rule: they can only do what you approve. On a WordPress site, a contact form plugin can ship an update with a backdoor, and that backdoor can read your database, write to your files, and create new admin users. Nothing in WordPress stops it, because every plugin runs with the same access as WordPress itself.
EmDash was built to break that pattern. If you are new to the project, start with our guide on what EmDash CMS is, Cloudflare’s Astro-based CMS that it calls the spiritual successor to WordPress. The short version: EmDash keeps the plugin idea but locks every plugin inside a sandbox that only opens the doors you approve.
This guide explains how EmDash plugins work, what the sandbox blocks, how the permission system reads, where to find plugins today, and how to install them on your own server.
TL;DR (Too Long, Didn’t Read?)
- EmDash plugins come in two formats. Sandboxed plugins run in an isolated runtime; native plugins run inside your site with full access.
- Sandboxed plugins start with almost no access. They get their own private storage and nothing else until you approve more.
- Every plugin declares its permissions, called capabilities, in a manifest file such as
content:readornetwork:request. You approve them at install. - Network access works on an allowlist. A plugin can only call the hosts its manifest names.
- You find plugins in the official registry at plugins.emdashcms.com, inside your admin panel, on npm, and on GitHub.
- Before EmDash loads a registry plugin, it checks the publisher’s signed records and the bundle’s checksum.
- On Cloudflare, sandboxed installs need the Workers Paid plan. On a self-hosted Node.js server, plugins run in the free workerd sandbox.
What Is an EmDash Plugin?
An EmDash plugin is a package of code that adds features to your EmDash site by reacting to events, storing data, adding admin pages, or serving API routes. It is the same idea as a WordPress plugin, with one big difference: the plugin has to ask before it touches anything.
Think of a hotel keycard. In WordPress, every plugin gets a master key that opens every room. In EmDash, each plugin gets a card that opens only the rooms printed on it, and you decide what gets printed.
What Plugins Can Do
According to the official EmDash plugin docs, a plugin can:
- React to events such as content saves, media uploads, and scheduled tasks
- Store data in its own indexed collections and key-value storage
- Add admin pages and settings forms to the dashboard
- Serve API routes under
/_emdash/api/plugins/<id>/<route> - Make HTTP requests to hosts it declares in advance
- Send transactional email through your configured mail transport
Sandboxed vs Native Plugins
EmDash supports two plugin formats. The docs recommend sandboxed plugins unless you specifically need what only native plugins offer.
| Aspect | Sandboxed Plugins | Native Plugins |
|---|---|---|
| Where it runs | An isolated runtime, separate from your site | Inside your site’s main Astro process |
| Access | Only the capabilities you approve | Full access to the runtime |
| How you install it | Registry (admin panel) or sandboxed: [] in config |
npm package in plugins: [] in config |
| Updates | Registry plugins update without a redeploy | Requires a redeploy |
| Admin UI | Block Kit (JSON-described components) | React components |
| Extras | None | Portable Text renderers, page fragment injection |
| Best for | Almost everything | Deep integrations you fully trust |
Rule of thumb: treat a native plugin like WordPress code. It runs with full access, so install one only from a publisher you trust completely.
How the EmDash Plugin Sandbox Works
Here is what happens when a sandboxed plugin runs:
- The plugin declares its needs in a manifest file called
emdash-plugin.jsonc. - You review and approve those permissions in a consent dialog at install time.
- A sandbox runner loads the plugin in its own isolated process.
- The plugin talks to EmDash only through a bridge. It calls helpers like
ctx.http.fetch()instead of rawfetch(), and the bridge checks every call against the approved permissions.
The plugin never gets direct access to your database, file system, environment variables, or secrets. If it tries to do something outside its permissions, the call fails inside the sandbox and never reaches your site.
Cloudflare vs Self-Hosted: Two Sandbox Runners
The sandbox works differently depending on where you run EmDash.
| Aspect | Cloudflare Workers | Self-Hosted Node.js |
|---|---|---|
| Sandbox technology | Dynamic Workers via Worker Loader | workerd child process |
| Plan requirement | Workers Paid plan for registry installs | None, free and open source |
| CPU limit | 50 ms per call | Not enforced |
| Wall time limit | 30 seconds | 30 seconds |
| Subrequest limit | 10 per call | Not enforced |
The catch worth knowing: the Node.js runner isolates permissions but does not cap CPU or memory. A buggy plugin cannot steal your data, but it can still eat server resources. On a self-hosted server, give EmDash enough headroom and watch resource usage after you add a new plugin.
The Capability Model: How EmDash Plugin Permissions Work
Capabilities are the permissions a plugin asks for. EmDash defines more than 20 of them, and each one grants a single, narrow ability. Here are the ones you will see most often:
| Capability | What It Allows |
|---|---|
content:read |
Read entries, translations, and public URLs |
content:write |
Create, update, and delete entries |
content:publish |
Publish, unpublish, and schedule entries |
media:read |
Read media records and metadata |
media:write |
Upload and delete media files |
media:metadata:write |
Update alt text, captions, and focal points |
comments:moderate |
Approve, reject, or trash comments |
taxonomies:write |
Create terms and change assignments |
redirects:write |
Create, update, and delete redirect rules |
users:read |
Look up user accounts by ID or email |
email:send |
Send email through your configured transport |
network:request |
Call external hosts listed in the manifest |
network:request:unrestricted |
Call any public host |
The full capability reference lists every option. Notice how granular they get: an image alt-text plugin can request media:metadata:write without ever gaining the right to delete your media.
Network Access Uses an Allowlist
A plugin that requests network:request must also list the exact hosts it will call in allowedHosts:
{
"slug": "search-sync",
"capabilities": ["content:read", "network:request"],
"allowedHosts": ["api.search-provider.com"]
}
That plugin can read your posts and send them to its search service, and nothing else. It cannot edit content, and it cannot quietly send your data to a different server. Even network:request:unrestricted still blocks private and internal addresses.
What Plugins Cannot Do
No matter what you approve, a sandboxed plugin cannot:
- Read the file system, environment variables, or platform bindings
- Call
fetch()directly - Read another plugin’s storage
- Create new collections or change field definitions
- Override an edit lock an administrator holds
Updates Ask Again
If a plugin update adds a new capability, EmDash shows you a capability diff and waits for fresh approval before the new version activates. A plugin cannot quietly gain network access in version 2.1 that it never asked for in 2.0.
Where to Find EmDash Plugins
The ecosystem is young, but you already have five places to look.
1. The Official Plugin Registry
Browse plugins.emdashcms.com to search plugins by name and filter by category. Each plugin page shows its publisher and the permissions it requests.
2. The Registry Inside Your Admin Panel
You do not need to leave your site. Open the Registry section of the EmDash admin, search by title, description, or a full public name such as @example.com/my-gallery, and install from there.
3. First-Party Plugins From the EmDash Team
The EmDash repository ships reference plugins, including an audit log that tracks content and media changes, a webhook notifier that sends JSON payloads to external URLs, and an embeds plugin. These make good templates if you want to build your own.
4. npm Packages
Native plugins, and config-managed sandboxed plugins, install as npm packages. You add them to your Astro config under plugins: [] (native) or sandboxed: [] (sandboxed), then redeploy.
5. GitHub and the Community
Developers publish open-source plugins on GitHub. Check the license, the last commit date, and the requested permissions before you install anything from an unofficial source.
How the Plugin Registry Keeps Releases Honest
The EmDash registry runs on AT Protocol, the decentralized network behind Bluesky. Publishers sign each release and store the record in their own account, so no single company controls what gets published.
Before EmDash loads a registry plugin, it checks:
- The publisher’s current signed records
- The bundle’s checksum, name, and version
- The permissions the release requests
- Build provenance, if the publisher requires it
If a publisher’s handle stops resolving, the admin panel flags it as INVALID HANDLE and blocks the install. That design makes it much harder for an attacker to slip a tampered release into your site.
How to Install an EmDash Plugin
From the Admin Panel
- Sign in as a user with the
plugins:managepermission. - Open Registry and search for the plugin.
- Review the publisher, verification status, and requested permissions.
- Pick a release and click Install.
- Approve the permissions in the consent dialog.
Enable the Sandbox on a Self-Hosted Server
On Node.js, EmDash needs the workerd sandbox runner before it can run sandboxed plugins. Install it with:
npm install @emdash-cms/sandbox-workerd workerd
Then reference @emdash-cms/sandbox-workerd/sandbox as the sandbox runner in your EmDash config. On xCloud EmDash hosting, the Docker + NGINX deployment runs plugins in the workerd sandbox, so you do not need to set this up yourself.
Uninstalling a Plugin
Uninstalling keeps the plugin’s stored data by default, so you can reinstall later without losing settings. Choose to delete the data during uninstall if you want a clean slate.
EmDash Plugins vs WordPress Plugins
| Aspect | EmDash Plugins | WordPress Plugins |
|---|---|---|
| Language | TypeScript | PHP |
| Default access | Private storage only | Full site, database, and files |
| Permissions | Declared and approved per capability | None |
| Network calls | Allowlisted hosts | Unrestricted |
| Update safety | New permissions need fresh approval | Updates apply with the same full access |
| Release verification | Signed records and checksums | Directory review at submission |
| Ecosystem size | Small and growing | Very large |
| Compatibility | EmDash only | WordPress only |
The honest take: WordPress wins on choice, EmDash wins on containment. If your site depends on WooCommerce or a mature membership plugin, WordPress still makes sense, and our managed WordPress hosting keeps it fast and patched. If you are starting fresh and plugin security keeps you up at night, EmDash’s model is a real step forward.
Tips for Choosing EmDash Plugins Safely
Tip 1: Read the Permissions Before the Description
A plugin’s capabilities tell you more than its marketing copy. A social sharing plugin needs content:read and network:request. If it also asks for users:read or content:write, ask why.
Tip 2: Be Wary of Unrestricted Network Access
network:request:unrestricted makes sense for webhook tools that call URLs you supply. For almost anything else, expect a short allowedHosts list.
Tip 3: Prefer Sandboxed Over Native
Native plugins run with full access. Use them only when you need a React admin screen or page fragment injection, and only from a publisher you trust.
Tip 4: Test on a Demo Site First
Install new plugins on a throwaway copy of your site before production. On xCloud, a Demo Site gives you a test domain before you go live.
Tip 5: Back Up Before You Install
A sandbox protects your data from the plugin, not from a bad content edit you approve. Take a backup of the database and media volumes first, as covered in our guide to backing up and restoring Docker apps.
Tip 6: Watch Server Resources After an Install
Because the Node.js runner does not cap CPU or memory, a heavy plugin can slow your site. Check your server graphs for a day after adding one, and keep your VPS security basics in place.
Run EmDash Plugins on Your Own Server With xCloud
On Cloudflare, sandboxed plugin installs require the Workers Paid plan. On your own server, the workerd sandbox costs nothing extra, and you keep your content, media, and plugin data on infrastructure you control.
xCloud EmDash hosting deploys EmDash on a Docker + NGINX server, with plugins running in the workerd sandbox. Here is how to get started:
- Sign up for xCloud and go to Sites → New Site → One Click Apps, then choose EmDash.
- Choose a server and pick Demo Site or Go Live with your domain.
- Open the EmDash admin, sign in, and browse the plugin registry.
Follow the full walkthrough in our doc: How to Deploy EmDash CMS in One Click on xCloud.
What you get with an EmDash server on xCloud:
- Isolated workerd plugins for sandboxed registry installs
- HTTPS, which passkey sign-in depends on
- Backups of your database and media, as part of the standard xCloud site operations
- Logs and domain setup from the same site dashboard you use for other apps
- A server you control, so you can manage it with AI agents through the xCloud MCP server
The honest trade-off: a bare VPS costs less if you enjoy setting up workerd, NGINX, SSL, and backups yourself. What you pay for with a managed plan is the time you get back.
Pick Your First EmDash Plugin This Week
EmDash plugins flip the WordPress model. Instead of trusting every plugin with your whole site, you grant each one exactly what it needs, and EmDash enforces that line in a sandbox.
The ecosystem is still small, so you will not find a plugin for everything yet. Start with one plugin you actually need, such as a pre-publish checker or a newsletter tool, read its permissions, and install it on a demo site first.
Whichever plugin you choose, the habit of reading permissions before you install will serve you well on any platform.
If you found this guide useful, subscribe to our blog for more tutorials and tips on web hosting and server management.
Frequently Asked Questions
Are EmDash plugins free?
EmDash itself is free under the MIT license. Each plugin publisher sets its own plugin license and pricing, so check the plugin page before you install.
Can I use WordPress plugins in EmDash?
No. EmDash uses no WordPress code, and its plugins use a TypeScript API. You can migrate your WordPress content, but you need EmDash equivalents for plugin features. Learn more in our guide to what EmDash CMS is.
Do EmDash plugins require Cloudflare?
No. On Cloudflare, sandboxed registry installs need the Workers Paid plan. On a Node.js server, plugins run in the free workerd sandbox.
Are sandboxed plugins completely safe?
No sandbox makes a plugin trustworthy. It limits what the plugin can reach, but a plugin still gets every permission you approve. Install from publishers you trust and keep backups.
I installed a plugin, but it cannot reach its external API. What should I do?
Check the plugin’s allowedHosts list. EmDash blocks any host the manifest does not name, so the publisher needs to add the domain in a new release. Also confirm your server allows outbound HTTPS traffic.
