Skip to content

Install

Use this page to add Mika to a host Astro + EmDash app. It covers package mode, plugin registration, the first host-owned files, and the verification checks that prove the wiring exists.

Check Compatibility And Publication before treating a registry install as available. In this workspace, Mika is a 0.1.0 release candidate and the seeded template uses file:../emdash-mika; verify publication before making npm install @bnomei/emdash-mika the only documented path.

  • An existing Astro + EmDash app.
  • Node >=22.12.0; the seeded template uses Node >=22.13.0.
  • An install mode chosen from Compatibility And Publication.
  • A planned api, either fixture overrides or a production createMikaBackendApi() composition.
  • Dynamic or server rendering for request-bound pages such as cart, account, checkout, downloads, and webhooks.

When the package is published, install it in an Astro + EmDash app and pin EmDash inside Mika’s current peer range:

Terminal window
npm install @bnomei/emdash-mika "emdash@>=0.22.0 <1.0.0"

For local workspace development before publication, use a file dependency:

{
"dependencies": {
"@bnomei/emdash-mika": "file:../emdash-mika",
"emdash": ">=0.22.0 <1.0.0"
}
}

Register Mika’s descriptor in the host app’s existing EmDash config, and point it at a runtime entrypoint that can import live functions:

import { fileURLToPath } from "node:url";
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { mikaPlugin } from "@bnomei/emdash-mika";
const mikaEntrypoint = fileURLToPath(new URL("./src/plugins/mika-plugin.ts", import.meta.url));
export default defineConfig({
integrations: [
emdash({
// Keep the host's database, storage, admin, and other EmDash options here.
plugins: [mikaPlugin({ entrypoint: mikaEntrypoint })],
}),
],
});

api is host-owned and belongs in the runtime entrypoint, not descriptor options. Build it with createMikaBackendApi() and provider adapters, or supply explicit MikaApiOverrides for tests, fixtures, or custom backends.

This registration happens in the same file where EmDash itself is configured. The official EmDash project shape keeps database, storage, plugin, and admin configuration in astro.config.mjs; Mika joins that plugin list rather than replacing EmDash content or Astro routing.

Descriptor Options Versus Native Entrypoints

Section titled “Descriptor Options Versus Native Entrypoints”

mikaPlugin() descriptor options are JSON-safe: entrypoint, maintenance, and assertWired. Live functions, provider clients, stores, repositories, and policy callbacks do not belong in the descriptor path.

Create the entrypoint module and call the runtime factory from @bnomei/emdash-mika/server:

src/plugins/mika-plugin.ts
import { createMikaPlugin, type MikaCreatePluginOptions } from "@bnomei/emdash-mika/server";
import { api } from "../lib/mika-api";
export function createPlugin(options: MikaCreatePluginOptions = {}) {
return createMikaPlugin({ ...options, api });
}

The seeded GitHub template uses #mika-template-plugin for this reason. Its package.json maps that import alias to src/plugins/mika-template-plugin.ts, and astro.config.mjs registers mikaPlugin({ entrypoint: "#mika-template-plugin" }).

A working install needs three host-owned pieces:

  1. The backend APIapi, composed with createMikaBackendApi() (repositories, providers, notifications, IDs, hashing, config). For tests or fixtures you can pass plain MikaApiOverrides method overrides instead of a full backend. See the Backend And Provider guide.
  2. The native plugin entrypointsrc/plugins/mika-plugin.ts exports createPlugin() and returns createMikaPlugin({ ...options, api }).
  3. The Astro Actions registry — copy src/actions/{index,mika}.ts and export server.mika = createMikaActions({ api }) so browser forms can use actions.mika.*.queryString. See the Astro Storefront guide.

Provider secrets (Stripe keys, webhook secret, email credentials) are host-owned environment configuration. Mika ships none of them; add them when you wire each provider adapter.

For smoke tests and fixtures, explicit MikaApiOverrides are fine. The seeded template uses local fixture functions to prove catalog, cart, wishlist, checkout, account, download, and admin flows.

For production, use createMikaBackendApi() with durable repository ports, a provider registry, IDs, clocks, hashing, notification hooks, defaults, and checkout config. Stripe wiring does not replace repositories; the Stripe adapter only handles provider-facing checkout, portal, invoice, refund, sync, and webhook behavior.

Mika’s cart, account, and checkout pages are request-bound, so they export prerender = false. Run the host with output: "server" (or keep those routes dynamic in a hybrid build) behind an Astro adapter such as @astrojs/node or @astrojs/cloudflare. EmDash itself needs a database and storage adapter; the ⓣ seeded GitHub template repo uses SQLite + local files on Node, and sketches D1 + R2 on Cloudflare.

Astro prerenders pages by default. A copied Mika page that reads cookies, sessions, carts, account state, or action results must render on demand. You can do that per route with export const prerender = false, or set output: "server" for the host and opt individual static pages back into prerendering.

For a new integration, the shortest useful path is:

  1. astro.config.mjs registers EmDash and mikaPlugin({ entrypoint }).
  2. src/lib/mika-api.ts exports the host-owned API implementation.
  3. src/plugins/mika-plugin.ts exports createPlugin() and calls createMikaPlugin({ api }).
  4. src/actions/mika.ts re-exports Mika’s action factory.
  5. src/actions/index.ts exports server.mika = createMikaActions({ api }) and optional host guards.
  6. A host product page calls createMika(Astro, { api }) and renders copied purchase components.

See the Integration File Map for the full import/copy distinction.

The commerce contracts do not require Kumo or React, but the copyable Astro templates do. If you copy the Kumo-backed UI files, install and register the UI dependencies:

Terminal window
npm install @cloudflare/kumo @phosphor-icons/react react react-dom @astrojs/react

Add react() to the host’s existing integrations array; keep emdash(...) and any other integrations already present:

import react from "@astrojs/react";
export default defineConfig({
integrations: [
react(),
// Keep the host's existing integrations here.
],
});

Also copy or import styles/kumo.css. Kumo is the template UI layer; it is not Mika’s commerce runtime.

After the first files exist, run the same checks as the First Integration Checklist:

  • build the host app;
  • load one product page that calls createMika(Astro, { api });
  • submit one form whose action uses actions.mika.cart.add.queryString;
  • confirm Astro.getActionResult(actions.mika.cart.add) renders feedback;
  • confirm checkout start either returns a provider redirect or a clear provider/configuration error;
  • open /_emdash/api/plugins/mika/catalog/sellables?collection=products&id=<product-id> and /_emdash/api/plugins/mika/sellables/availability?sellableId=<sellable-id> as public reads, using IDs from your host data;
  • keep protected mutation routes behind Actions or host-owned endpoints.

If you have not seen a complete source-backed host app yet, run the seeded template quickstart. After the existing app is registered, continue with First Product Page.

Mika targets Astro, EmDash, TypeScript, and optional UI/provider helpers. Check ../emdash-mika/package.json for the current peer ranges before publishing install instructions.

  • ../emdash-mika/README.md
  • ../emdash-mika/package.json
  • ../emdash-mika/src/plugin.ts
  • ../emdash-mika/src/templates/astro/README.md
  • ../emdash-mika-template/astro.config.mjs
  • ../emdash-mika-template/src/plugins/mika-template-plugin.ts
  • ../emdash-mika-template/package.json