emdash

Getting Started with EmDash

EmDash is an e-commerce plugin for modern storefronts. This guide walks you through installation, configuration, and deploying your first store.

Installation

Add the EmDash e-commerce plugin to your project:

bun add @emdash-plugins/ecommerce

Or with npm:

npm install @emdash-plugins/ecommerce

Configuration

Create an emdash.config.ts in your project root:

import { defineConfig } from 'emdash'
import { ecommercePlugin } from '@emdash-plugins/ecommerce'

export default defineConfig({
  plugins: [
    ecommercePlugin({
      stripe: {
        publicKey: process.env.STRIPE_PUBLIC_KEY,
        secretKey: process.env.STRIPE_SECRET_KEY,
      },
    }),
  ],
})

Set your environment variables:

# .env.local
STRIPE_PUBLIC_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...

Add Products

Define your product catalog in content/products/:

// content/products/t-shirt.ts
import type { Product } from '@emdash-plugins/ecommerce'

export const tShirt: Product = {
  id: 'tshirt-classic',
  name: 'Classic T-Shirt',
  description: 'A comfortable everyday tee.',
  price: 2900, // in cents
  currency: 'usd',
  images: ['/images/tshirt-front.jpg'],
  variants: [
    { id: 'sm', label: 'Small', inventory: 50 },
    { id: 'md', label: 'Medium', inventory: 100 },
    { id: 'lg', label: 'Large', inventory: 75 },
  ],
}

Deploy

Deploy to Cloudflare Pages with:

bun run deploy

Your store will be live at your-project.pages.dev.


API Reference

PluginContext

Each plugin receives a PluginContext on every request:

interface PluginContext {
  request: Request
  env: Record<string, string>
  fetch: (url: string, init?: RequestInit) => Promise<Response>
  kv: KVNamespace
}

Constraints:

  • Max 50ms CPU time per request
  • Max 10 outbound fetch calls
  • No shared mutable state between requests

definePlugin

import { definePlugin } from 'emdash'

export default definePlugin({
  name: 'my-plugin',
  version: '1.0.0',
  hooks: {
    'cart:add': async (ctx, item) => {
      // called when an item is added to the cart
      return item
    },
    'checkout:complete': async (ctx, order) => {
      // called after a successful payment
      await ctx.fetch('https://my-fulfillment.com/orders', {
        method: 'POST',
        body: JSON.stringify(order),
      })
    },
  },
})

Block Kit

Block Kit is EmDash's UI component system for building storefront layouts:

import { Blocks, ProductCard, CartButton } from '@emdash-plugins/ecommerce/blocks'

export function ProductGrid({ products }) {
  return (
    <Blocks.Grid columns={3}>
      {products.map((p) => (
        <ProductCard key={p.id} product={p} />
      ))}
    </Blocks.Grid>
  )
}