Self-hosted .stage deck platform for teams.
Shared library · notes & annotations · admin invites · Docker-deployable.
Self-hosted .stage presentation platform built on Prisma + SQLite + Hono +
React 19, deployable to any VPS via Docker Compose. Pro is a thin shell around
the Lite open-source packages (@slidestage/core, @slidestage/ui,
@slidestage/lite-preset) — it adds multi-user storage, notes/annotations
persistence, admin invites, and Docker-based deployment.
Foundation packages (consumed via npm):
@slidestage/brand— SVG / PNG marks, favicons, social cards and design tokens shared across the family. ·@slidestage/spec— TypeScript types and runtime validators for the.stagecontainer schema. ·
Regenerate this block with
pnpm render:ecosystem. The product registry is owned upstream in@slidestage/brand.
Status — v0 feature-complete (on branch
rebuild-pro-from-zero). The full stack — API, web, packages, schema, Docker compose, nginx reverse-proxy, boundary checker (+ its own self-test), fixture generator — is implemented and passescheck:boundaries/typecheck/ 18 tests /build. As of Phase A.A4 (2026-05-26) Lite packages come from the public npm registry (the previousvendor/tarball bridge has been removed). Thedocker compose build && uppath is wired and statically validated; running it requires a Docker daemon (Docker Desktop / OrbStack / Colima) with outbound network access toregistry.npmjs.orgat build time.Documentation:
docs/ARCHITECTURE.md·docs/API_CONTRACT.md·docs/AUTH_FLOW.md·docs/DEPLOYMENT.md·docs/LITE_PACKAGE_BOUNDARY.md
SlideStagePro/
├── apps/
│ ├── api/ Hono server, Prisma client, Better Auth, storage
│ └── web/ Vite + React 19 + react-router v7 client
├── packages/
│ ├── pro-preset/ Pro-only SlideStage plugin (proPreset factory)
│ └── pro-shared/ Pro-internal shared types/constants
├── prisma/
│ ├── schema.prisma Single SQLite schema (Better Auth + business + invites)
│ └── migrations/ Versioned SQL migrations (auto-applied on boot)
├── infra/
│ ├── docker/ Dockerfile.api, Dockerfile.web, api-entrypoint.sh
│ └── nginx/ edge nginx.conf + in-web-image web.conf
├── scripts/
│ ├── check-boundaries.mjs CI gate: enforce Lite ↔ Pro boundary (rejects all file: refs)
│ ├── check-boundaries.test.mjs Self-test: forge violations, assert checker fails
│ └── build-fixtures.mjs Emit canonical .stage fixtures for manual QA
├── fixtures/ Smoke-test .stage files (valid + 3 invalid)
├── docs/ Architecture · API · Auth · Deployment · Boundary
└── docker-compose.yml api + web + nginx stack with persistent volume
# 1) one-time setup
# Optional for local dev: dev mode has safe local defaults.
# Copy .env.example to .env when you want custom secrets/admin credentials.
# 2) install + migrate + run
# @slidestage/{core,ui,lite-preset} are fetched from the npm registry.
pnpm install
pnpm db:migrate:dev
pnpm dev # runs apps/api + apps/web in parallelThe API listens on :3000, the web dev server on :5173. Vite proxies
/api to the API (see apps/web/vite.config.ts).
cp .env.example .env
# set BETTER_AUTH_SECRET, BOOTSTRAP_ADMIN_EMAIL, BOOTSTRAP_ADMIN_PASSWORD
docker compose build
docker compose up -d
curl http://localhost/api/healthThe compose stack runs three services:
api— Node 22 + Hono + Prisma, mountsslidestage-datavolume at/data.web— Nginx serving the Vite-built bundle.nginx— Edge reverse proxy on port 80, routes/api/*→ api,/→ web.
pnpm check:boundaries # 0 violations on prose-free files
pnpm check:boundaries:self-test # forge a violation per rule, verify checker fails
pnpm typecheck # tsc across all 4 workspace packages
pnpm test # 18 vitest cases across api + web
pnpm build # api dist + packages dist + vite SPA bundle
pnpm fixtures:check # verify fixture .stage files exist + matchAll six green = the diff is safe to merge.
Pro never copies Lite source code. It consumes Lite packages by semver from the public npm registry:
"@slidestage/core": "^0.1.1",
"@slidestage/ui": "^0.1.1",
"@slidestage/lite-preset": "^0.1.1"(As of Phase A.A4, 2026-05-26, the previous vendor/*.tgz bridge has been
removed; any file: dependency in any package.json is now a CI violation.)
Forbidden patterns (enforced by scripts/check-boundaries.mjs):
file:../SlideStageLiteorlink:../SlideStageLitein any dependencyimportfrom"../SlideStageLite/..."- Re-declaring
manifestSchema/assertSafePath/loadDeck(must come from@slidestage/core) VITE_APP_EDITIONorisProedition branchingapps/apiimportingreact/react-domapps/webimporting@prisma/client/better-sqlite3/hono


