Development - UpstandPlatform/OpenRive GitHub Wiki
Requirements: Bun 1.4+ and git. Optional: Docker (to test the PostgreSQL service and the image).
bun install
bun run devUseful URLs: / (files), /users, /editor/<id>, /preview/<id>, /api/health.
The Rive SDKs are vendored as git submodules in vendor/, but nothing needs them for day-to-day work: the editor
renders with the @rive-app/canvas-advanced npm package that bun install copies into apps/web/public/rive. Run
bun run rive:init when you want them, and see Rive SDK submodules for updating the forks or
rendering with your own build.
In development, the editor store is exposed as window.__riveEditor for debugging in the browser console:
__riveEditor.getState().doc // the current RiveDoc
__riveEditor.getState().selectionThis repo is a Bun workspace driven by Turborepo:
bun installat the root, andbun run <script>from the root for cross-package tasks. It uses Next.js 16. APIs differ from older versions: route handlerparamsare a Promise,proxy.tsreplaces middleware, andPageProps/RouteContexttypes are generated. Checknode_modules/next/dist/docs/when in doubt (seeAGENTS.md).
apps/web/ editor UI + REST API
apps/cli/ CLI (OpenTUI), MCP server, shared project store
apps/desktop/ Electrobun desktop app
packages/rive/ .riv format and editing core (DOM-free)
packages/db/ Drizzle schema, migrations and queries
packages/shared/ zod schemas and shared types
packages/ui/ shared React components
vendor/ forked Rive SDK submodules
docs/ user and operator documentation
contribution/ contributor guides
The web app's source is organized under apps/web/src/:
apps/web/src/app/ pages and REST API route handlers
apps/web/src/components/ shared UI and editor panels
apps/web/src/lib/ browser helpers, state and rendering
apps/cli/src/index.ts CLI launcher
See Architecture for the data flow.
Install local test/render Chromium with bunx [email protected] install chromium (Linux CI adds --with-deps).
bun run test includes 27 bone scenarios and official-runtime pixel checks for bind, pose, scale, mirror,
rebind/unbind, and image meshes. bun run test:browser starts an isolated scratch editor and exercises actual pointer
gestures, Inspector controls, undo, deformed vertex dragging, read-only and Animate restrictions, and save/reload.
It closes its browser/server and removes its scratch database afterward. Stop an existing dev server first; Next
development processes share the .next directory. CI and release validation run both suites.
Most features touch these layers, in this order:
-
Core (
packages/rive/src/*.ts): a pure function that edits aRiveDoc. Keep it DOM-free and name-addressable when it's user-facing (seeapi.ts). Add a round-trip test if it creates new object types. -
CLI / MCP (
apps/cli/): expose it if it's useful for automation (registerToolinmcp-server.ts). -
UI: call it inside
useEditor.getState().commit((doc) => …), so it's one undo step. -
Action (
apps/web/src/components/editor/actions.ts): register a command with label, category, default keys,when,enabledandrun. Menus and the shortcuts dialog pick it up automatically. -
Docs: update
docs/.
{ id: 'object.center', label: 'Center on artboard', category: 'Arrange', keys: ['Alt+C'], edits: true,
enabled: hasSelection, run: () => st().commit((doc) => centerSelection(doc, st().selection)) },Then reference it in a context menu with act('object.center') in menus.ts.
The tab list is in Editor.tsx (leftTab), and the store type is leftTab in editor.ts. See AssetsPanel.tsx
for a complete example with import, context menus and drag and drop.
Edit packages/db/src/schema.ts, then run bun run db:generate: drizzle-kit writes the SQL migration and
scripts/embed-migrations.ts embeds it so bundled runtimes (standalone server, Docker, desktop) can apply it. Commit
both. Queries belong in packages/db/src/repository.ts — nothing else talks to the database. Test both connections:
bun run cli db status # embedded PostgreSQL
bun run db:up
DATABASE_URL=postgres://openrive:openrive@localhost:5432/openrive bun run cli db status- Object types and properties come from
core-defs.json. To update to a newer runtime, runbun scripts/generate-core-defs.js <rive-runtime>/dev/defs. - Index references between objects are converted to ids in
document.ts(REF_SPACES). New reference properties must be registered there. - Array order is draw order (earlier draws on top), so use
insertObjects/moveBeforefromops.ts. - Inspect any file:
bun scripts/dump.ts file.riv.
bun run db:up # docker-compose.dev.yml
DATABASE_URL=postgres://openrive:openrive@localhost:5432/openrive bun run dev
bun run db:downdocker compose up -d pulls the published image (ghcr.io/upstandplatform/openrive). To run your own build of it:
docker build -t openrive:local .
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build # app + postgresCI publishes the image for amd64 and arm64 on every push to main and every v* tag, always as :latest and as
the commit it was built from, plus :1.2.3 and :1.2 for a tag — .github/workflows/image.yml. Pull requests that
touch the Dockerfile or a compose file build it without publishing.
bun run --cwd apps/desktop build:server # Next.js standalone bundle
bun run build:desktop # Electrobun installers in apps/desktop/artifactsElectrobun builds only for the host platform; CI builds all three (.github/workflows/desktop.yml).
This page is generated from contribution/development.md. Suggest an edit.