Architecture

Four moving parts

PartWhat it isRuns on
Selva plugin (Selva.gha)The schema designer + bridge to a live RhinoAuthor’s Rhino, and the Compute server
Selva web app (@selvajs/selva)The schema runnerYour server
Rhino.ComputeHeadless Rhino that solves over HTTPA Windows VM
ProviderPluggable auth / data / storage backendIn-process with the web app

Everything else (@selvajs/ui, schemas, compute, visualization, solve, server, platform) is a shared library these four are built from.

The schema is the contract

A schema describes a definition’s web interface: which inputs are exposed, what control each one maps to, the layout, and the outputs. You create it in the designer, and the web app reads it to render the UI.

Its shape is defined once in ui-schema.json and code-generated into both stacks: TypeScript for the web app, C# for the plugin. CI fails on drift. That’s what keeps a C# plugin and a TS web app speaking the same language without a hand-written API spec.

Two runtime paths

Design time: WebSocket to a live Rhino. While you build the interface, the plugin runs a WebSocket server inside your Rhino, on loopback (port 8765 by default, or a free one if that is taken). The designer connects to it, discovers parameters, and writes the schema back into the .gh. Changes round-trip live.

Run time: HTTP to Rhino.Compute. Once deployed there’s no live Rhino. The web app loads the saved schema and sends inputs to Rhino.Compute over HTTP on each change. Compute solves headlessly and returns geometry to the Three.js viewer.

HTTP inputs

geometry

HTTP solve

geometry

auth / data / storage

End user's browser

controls + 3D viewer

@selvajs/selva

schema + provider

Rhino.Compute

headless Rhino + Selva.gha

Provider

(your backend)

The packages

PackageRole
@selvajs/schemasThe schema contract + TS/C# generators. Source of truth for both stacks.
@selvajs/plugin-uiThe schema designer UI. Embedded into Selva.gha.
@selvajs/selvaThe deployable web app.
@selvajs/uiShared Svelte components, theme, and the Svelte shells around the viewer.
@selvajs/computeType-safe Rhino.Compute client and data trees. Pure solve/data, no renderer. See Build your own app.
@selvajs/visualizationHeadless viewer core: solve response → Three.js. Layers scenerenderparseshared.
@selvajs/solveThe solve flow, both sides of the wire (/client, /server, /shared).
@selvajs/serverServer building blocks: compute limits and client cache, rate limit, SSRF guard, definitions, tokens, access.
@selvajs/platformProvider interfaces, no implementations. See Providers.
@selvajs/*-providerConcrete provider implementations.
@selvajs/cliScaffolds and operates a deployment. See CLI.

On the .NET side, schema and drawing logic sit apart from the Rhino-coupled Selva.GH/Selva.Rhino. That half has no Rhino dependency, so it’s unit-testable.

What stays in sync

  • Plugin ↔ web app. Both generate from ui-schema.json, and CI fails on drift.
  • Providers ↔ interfaces. Every adapter runs a conformance suite, so a new provider behaves like the reference one.

Next