The Plugin Marketplace Opportunity
EmDash's sandboxed plugin architecture opens a new distribution channel for developers targeting the Astro + Cloudflare ecosystem. Unlike traditional CMS plugin stores (WordPress, Shopify), the EmDash Marketplace is purpose-built for modern Jamstack sites: lightweight, serverless, and deployable via D1. This guide walks through every step of launching a plugin from concept to listing approval.
Why the EmDash Ecosystem Matters
EmDash sites run on Cloudflare Pages with D1 databases, giving them global edge distribution, zero cold starts, and sub-50ms TTFB. Plugin developers can tap into this performance advantage without managing infrastructure. The marketplace currently serves over 650 published sites, with categories spanning blogging, marketing automation, e-commerce, and content scheduling.
Launching a plugin here means:
- **Instant distribution** to an existing audience of EmDash site operators
- **D1-native storage** with no external database to configure
- **Built-in admin UI hooks** for configuration forms and dashboards
- **Automatic CDN cache purging** when plugin data changes
Step 1: Scaffold Your Plugin Project
Every EmDash plugin starts with a standard directory structure. Use the EmDash CLI to bootstrap:
```bash
npx emdash create-plugin my-plugin --template basic
```
This generates:
```
my-plugin/
manifest.yaml # Plugin metadata, hooks, and permissions
src/
index.ts # Main entry point
config.ts # Configuration schema
dist/
plugin.js # Compiled output (auto-generated)
README.md
```
The `manifest.yaml` is the most critical file. It declares which EmDash hooks your plugin hooks into, what D1 tables it creates, and what permissions it needs:
```yaml
name: my-plugin
version: 1.0.0
hooks:
- post.publish
- admin.settings
requires:
- d1:read
- d1:write
```
Step 2: Implement the Plugin Logic
The sandboxed runtime restricts plugins to a safe subset of JavaScript. Key constraints:
- No direct filesystem access (use D1 for persistence)
- No raw network requests (use the built-in fetch wrapper with rate limiting)
- DOM access only through provided AST helpers (no direct document manipulation)
Here is a practical example of a plugin that adds a scheduled-publish toggle to posts:
```typescript
import { definePlugin, D1 } from 'emdash/plugin';
export default definePlugin({
name: 'scheduled-publish',
hooks: {
async 'post.beforeRender'(context) {
const { post, db } = context;
const schedule = await db.prepare(
'SELECT published_at FROM ec_schedules WHERE post_id = ?'
).bind(post.id).first();
if (schedule && new Date(schedule.published_at) > new Date()) {
return { ...post, status: 'scheduled', scheduledAt: schedule.published_at };
}
return post;
},
},
});
```
Step 3: Test Locally with the EmDash Dev Server
Before submitting to the marketplace, test your plugin against a local EmDash site:
```bash
npx emdash dev --plugins ./my-plugin
```
The dev server loads your plugin, mounts its D1 tables, and simulates the production sandbox. Run the full test suite:
```bash
npx emdash test --plugin ./my-plugin
```
This validates:
- Hook signature compatibility with the current EmDash runtime
- D1 query correctness (no syntax errors or missing columns)
- Memory and CPU budget compliance (plugins get 128MB heap, 10ms per hook)
- No circular dependency chains in hook execution order
Step 4: Package and Submit
When your plugin passes local tests, package it:
```bash
npx emdash plugin:package ./my-plugin --output ./my-plugin-1.0.0.zip
```
Submit via the EmDash admin panel under Settings > Marketplace > Submit Plugin. You will be asked for:
- **Plugin name** (must be unique marketplace-wide)
- **Version** (semver)
- **Icon URL** (512x512 PNG recommended)
- **Screenshots** (up to 3, showcasing admin UI integration)
- **Pricing tier** (Free, Freemium, or Paid via Stripe integration)
- **README** (markdown, rendered on the listing page)
Step 5: Navigate the Review Process
All plugins go through a two-stage review:
1. **Automated security scan**: The marketplace CI checks for eval(), dynamic require(), filesystem access, and network requests outside the allowed fetch wrapper. Violations are flagged and the submission is rejected with a report.
2. **Manual code review**: A human reviewer checks code quality, documentation completeness, and UX consistency with EmDash design patterns. Typical turnaround is 2–5 business days.
Pricing and Monetization Strategies
The marketplace supports three models:
- **Free**: Best for utility plugins and integrations. Builds adoption and brand visibility.
- **Freemium**: Core features free, premium features unlocked via Stripe subscription. Recommended for content tools and analytics plugins.
- **Paid**: One-time purchase or subscription. Best for specialized vertical solutions (e-commerce, membership, booking).
EmDash takes a 15% platform fee on paid transactions, competitive with Shopify's 15–30% and WordPress.org's 50% on some premium stores.
Common Launch Pitfalls
| Pitfall | Symptom | Fix |
|---------|---------|-----|
| Missing D1 migration | Plugin installs but D1 queries fail | Add DDL statements to `manifest.yaml` migrations block |
| Hook timeout | Admin UI hangs on certain pages | Profile your hook with `console.time()` and optimize D1 queries |
| Stale CDN cache | Users see old plugin output | Register a `cache.purge` hook in your manifest |
| Sandbox memory limit | Plugin crashes on large datasets | Batch D1 queries with LIMIT/OFFSET pagination |
Marketing Your Plugin Launch
Once approved, promote your listing:
- Share on the EmDash community forum with a demo video
- Cross-post to Astro Discord and Cloudflare Developer Discord
- Write a launch blog post (the EmDash content team can feature it)
- Offer a launch discount code for the first 30 days
A well-executed launch can drive 200–500 plugin installs in the first week, based on marketplace analytics from previous launches.