Skip to content

Mount the foundation

Kumiko ships identity, auth, and multi-tenancy as bundled features. You do not wire login, user tables, or tenant schemas by hand — you list your own features and flip one flag.

src/run-config.ts is the one place that lists what your app mounts:

export const APP_FEATURES = [
mailFoundationFeature,
mailTransportInMemoryFeature,
createRateLimitingFeature(),
createAuditFeature(),
createJobsFeature(),
adminShellFeature,
appShellFeature,
showPonyFeature,
] as const;
export const HAS_AUTH = true;
— from src/run-config.ts

HAS_AUTH = true makes composeFeatures pull in the bundled auth chain automatically: config, user, tenant, auth-email-password, secrets, sessions. You mount only what is specific to ShowPony (showPonyFeature and the operational plugins above).

Login on the apex host dashboard
Email/password gate before the dashboard loads

After bun dev:

  • Email/password login at /login on the apex (show-pony.localhost:4180) — chapter 12 adds the public landing on /
  • A seeded demo host: [email protected] / changeme
  • A seeded sysadmin: [email protected] / changeme (platform workspace — chapter 8)
  • Tenant-scoped writes and queries — isolation from the framework, not custom middleware
  • Admin shell (sidebar, topbar) ready for schema-driven screens in chapter 8

bin/server.ts passes APP_FEATURES and HAS_AUTH into runDevApp, seeds the demo admin, and sets up host routing (apex vs subdomain — detailed in chapter 4).

Demo events + RSVPs are seeded only in production (seedsDir in bin/main.ts — not on bun dev). Locally you create events in the dashboard or follow chapter 11.

// Single source of truth for show-pony feature composition.
// Both bin/server.ts (dev) and the kumiko-schema CLI build on this,
// so the runtime registry and generated schema never drift apart.
//
// HAS_AUTH=true → composeFeatures automatically pulls in the bundled auth chain
// (config/user/tenant/auth-email-password/secrets).
import { createAdminShellFeature } from "@cosmicdrift/kumiko-bundled-features/admin-shell";
import { createAuditFeature } from "@cosmicdrift/kumiko-bundled-features/audit";
import { billingFoundationFeature } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
import { capCounterFeature } from "@cosmicdrift/kumiko-bundled-features/cap-counter";
import { createComplianceProfilesFeature } from "@cosmicdrift/kumiko-bundled-features/compliance-profiles";
import { createJobsFeature } from "@cosmicdrift/kumiko-bundled-features/jobs";
import { mailFoundationFeature } from "@cosmicdrift/kumiko-bundled-features/mail-foundation";
import { mailTransportInMemoryFeature } from "@cosmicdrift/kumiko-bundled-features/mail-transport-inmemory";
import { createManagedPagesFeature } from "@cosmicdrift/kumiko-bundled-features/managed-pages";
import { createRateLimitingFeature } from "@cosmicdrift/kumiko-bundled-features/rate-limiting";
import { createSecretsFeature } from "@cosmicdrift/kumiko-bundled-features/secrets";
import { createTenantLifecycleFeature } from "@cosmicdrift/kumiko-bundled-features/tenant-lifecycle";
import { createTierEngineFeature } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
import { composePagesStack } from "@cosmicdrift/kumiko-dev-server/compose-stacks";
import { appShellFeature } from "./features/app-shell/feature";
import { showPonyFeature } from "./features/show-pony/feature";
import { DEFAULT_TIER, SHOWPONY_TIER_MAP } from "./features/show-pony/tier-map";
import { renderLegalLayout } from "./legal-layout";
import { resolveSubdomainPageTenant } from "./tenant-routing";
/** Overview screens + nav only — app-shell owns workspaces host/platform. */
const adminShellFeature = createAdminShellFeature({
registerWorkspaces: false,
includeTierAdmin: true,
});
export const APP_FEATURES = [
...composePagesStack({ wrapLayout: renderLegalLayout }),
createManagedPagesFeature({
resolveApexTenant: resolveSubdomainPageTenant,
allowCustomCss: false,
}),
mailFoundationFeature,
mailTransportInMemoryFeature,
createRateLimitingFeature(),
createAuditFeature(),
createJobsFeature(),
createTierEngineFeature({ defaultTier: DEFAULT_TIER, tierMap: SHOWPONY_TIER_MAP }),
createComplianceProfilesFeature(),
createTenantLifecycleFeature(),
billingFoundationFeature,
createSecretsFeature(),
capCounterFeature,
adminShellFeature,
appShellFeature,
showPonyFeature,
] as const;
export const HAS_AUTH = true;

📄 On GitHub: src/run-config.ts