Elsa Foundation Studio is a modular React studio shell hosted by ASP.NET Core. The repository owns the Studio module protocol, Vite React shell, TypeScript SDK, and sample class-library modules that contribute same-origin ESM assets and endpoints.
For a current map of the host, shell, modules, routing, API boundaries, and authentication flow, see the architecture tour.
For operator guidance on current run health and following incidents to exact runtime evidence, see Workflow run incidents.
These repositories develop the Elsa 4 preview. Elsa 3 uses the separate elsa-core and elsa-studio repositories.
- Try Elsa 4: run Workbench and Studio from published Docker images.
- Contribute to the server: follow the Elsa Foundation contribution guide.
- Contribute to Studio: follow the Elsa Foundation Studio contribution guide.
The host is composed from independently enabled Studio capabilities:
Elsa.Studio.Coredefines manifests, diagnostics, and the manifest collection event.Elsa.Studio.ApiexposesGET /_elsa/studio/modules.Elsa.Studio.Webhosts the root-mounted Vite shell.Elsa.Studio.Dashboardowns/dashboard, the Dashboard Widget slot, host-owned frames, loading, refresh, layout, and scoped preferences.Elsa.Studio.Attentioncontributes the ordinary wide/full Attention widget.Elsa.Studio.Workflows.Dashboardcontributes workflow portfolio and run-health widgets.Elsa.Studio.Samples.WeatherForecastcontributes a frontend route and deterministic sample endpoint.Elsa.Studio.ConsoleStreamdemonstrates a backend-scoped console stream module.Elsa.Studio.ExtensionBuilderis an optional module: the Extension Builder page plus its bridge relay to the backend's/_elsa/extension-buildersurface. It is not part of the default composition (see below).
The shell UX is adapted from elsa-workflows/elsa-foundation-designer main at 2a04fdb, without importing its Next.js runtime or product feature modules.
Studio is a modular monolith built on CShells. Each module is a class library that exposes a CShells feature (IShellFeature / IWebShellFeature) instead of being hardwired into the host. The host (Elsa.Studio.Web) does not call module-specific registration methods — it enables features per shell from appsettings.json:
{
"CShells": {
"Shells": {
"Default": {
"Features": {
"StudioApi": {},
"ConsoleStream": {},
"DashboardStudio": {},
"AttentionStudio": {},
"WorkflowsDashboardStudio": {},
"WeatherForecastSample": {}
},
"Configuration": {
"WebRouting": { "Path": "" }
}
}
}
}
}Removing a feature key (or setting the shell up differently) turns the corresponding module — its services, manifest contribution, and endpoints — on or off without code changes. WebRouting:Path of "" mounts the shell's endpoints at the application root.
Backend-targeted Studio modules should use the runtime backend base URL instead of the shell origin. The shell exposes it through /studio-runtime.js and the frontend SDK surfaces it as api.backend.http. If Studio:BackendBaseUrl is unset, the backend client falls back to the shell origin.
Features ship in:
| Feature name | Library | Contract |
|---|---|---|
StudioApi |
Elsa.Studio.Api |
IWebShellFeature |
ConsoleStream |
Elsa.Studio.ConsoleStream |
IWebShellFeature |
DashboardStudio |
Elsa.Studio.Dashboard |
IShellFeature |
AttentionStudio |
Elsa.Studio.Attention |
IShellFeature |
WorkflowsDashboardStudio |
Elsa.Studio.Workflows.Dashboard |
IShellFeature |
WeatherForecastSample |
Elsa.Studio.Samples.WeatherForecast |
IWebShellFeature |
ExtensionBuilderStudio |
Elsa.Studio.ExtensionBuilder |
IWebShellFeature (opt-in, not in the default shells.json) |
The host discovers in-box features only in the assemblies listed in StudioFeatureAssemblies (in Elsa.Studio.Web), plus installed Nuplane packages. CShells stops scanning host assemblies once that list is registered, so every new in-box feature needs its assembly added there, opt-in features such as ExtensionBuilderStudio included. Otherwise CShells skips the feature with a startup warning when shells.json enables it, and Feature Management cannot enable it. WeatherForecastSample is the exception: the host does not reference it, and it activates once its package (artifacts/packages/Elsa.Studio.Samples.WeatherForecast.*.nupkg) is installed into the packages feed. Until then, the startup warning for it is expected.
Extension Builder is not enabled by default: a default Studio has no Extension Builder navigation item, route or
bridge endpoints. To enable it, add its feature key to the Default shell in src/apps/Elsa.Studio.Web/shells.json
(or the mounted copy in a deployment):
{
"CShells": {
"Shells": {
"Default": {
"Features": {
"ExtensionBuilderStudio": {}
}
}
}
}
}The page relays every operation through the Studio management bridge (/_elsa/studio/backend-management/extension-builder/*),
so the host needs Studio:BackendServerBaseUrl (or Studio:BackendBaseUrl) and Studio:BackendModuleManagementApiKey
configured, and the backend must expose the Extension Builder surface. Against a backend without it, the page shows its
explicit "backend management unavailable" state.
Source setup status: The central
ConsoleLogStreaming.AspNetCorepin now uses1.1.0. Studio #579 records a restore with isolated package-cache, HTTP-cache, and CLI-home paths, a Studio.Web build, and affected console-stream/host tests for this correction. The complete source-development and paired browser journey remains tracked in Studio #566. The.NETcommands below are existing developer commands; the scoped checks do not establish a complete fresh-machine setup or source-edit journey.
pnpm install
pnpm build
dotnet build
dotnet testdotnet run --project src/apps/Elsa.Studio.Web/Elsa.Studio.Web.csprojOpen:
//dashboard/weather/diagnostics/modules/_elsa/studio/modules/_elsa/studio/diagnostics/console-logs/recent/_elsa/studio/diagnostics/console-logs/sources/_elsa/studio/diagnostics/console-logs/hub/_elsa/studio/samples/weather-forecast
When Studio:BackendBaseUrl points at an Elsa Server backend, the console panel expects that backend to expose its own console stream under:
/_elsa/server/diagnostics/console-logs/recent/_elsa/server/diagnostics/console-logs/sources/_elsa/server/diagnostics/console-logs/hub
The Studio front-end ships four npm packages you can use in any host app —
React or not. See runnable examples under examples/: react-host (Vite + React)
and vanilla-host (framework-free, no JSX).
npm install @elsa-workflows/studio-ui @elsa-workflows/studio-code-editor \
@elsa-workflows/studio-sdk @elsa-workflows/studio-workflows| Package | What it gives you |
|---|---|
@elsa-workflows/studio-sdk |
Contribution/registry types and runtime helpers for building an ElsaStudioModuleApi. |
@elsa-workflows/studio-ui |
Host-agnostic UI primitives (DataGrid, StatusChip, Toolbar, Tabs, Field, Inspector, feedback states) + tokens.css. |
@elsa-workflows/studio-code-editor |
StudioCodeEditor component + javaScriptLanguageAdapter. |
@elsa-workflows/studio-workflows |
The workflows module: register(api) + helpers, plus style.css. |
Peer dependencies: react & react-dom (^18/^19) for all; @tanstack/react-query (^5)
and @xyflow/react (^12) additionally for @elsa-workflows/studio-workflows.
Styles (order matters — tokens.css aliases the --studio-* layer onto your own primitives):
import "./theme.css"; // your layer-1 primitives (--background, --primary, …)
import "@elsa-workflows/studio-ui/tokens.css"; // the --studio-* token layer
import "@xyflow/react/dist/style.css"; // only if using studio-workflows
import "@elsa-workflows/studio-workflows/style.css";
@elsa-workflows/studio-uiships the design-token layer (tokens.css), not per-component visual rules. The examples include astudio-components.cssyou can copy as a starting point.
Preview builds (4.0.0-preview.<n>) publish to the elsa-4 feedz.io npm feed on every push to
main; published GitHub Releases ship the tagged version to npmjs.org (see
.github/workflows/packages.yml).
Elsa.Studio.Web can be built and run as a container image. Build from the repository root
(the build context must be the repo root):
pnpm install --frozen-lockfile
pnpm build
docker build -f src/apps/Elsa.Studio.Web/Dockerfile -t elsa-studio-web:local .
docker run --rm -p 8080:8080 \
-e Studio__BackendBaseUrl=https://your-elsa-server:443 \
elsa-studio-web:localSee docs/docker.md for the full runtime configuration surface
(environment variables, shells.json mounting, the optional packages/ feed volume, and
a compose snippet).
Elsa-owned material in this repository is licensed under the MIT License; see LICENSE. Third-party code, assets, and dependencies retain their respective license terms and notices.