Front-end recipes
The curiosity-ai/frontend-recipes repository is a library of self-contained, runnable examples for building custom front-ends on top of a Curiosity Workspace using the Mosaik front-end framework, the Tesserae UI library, and the h5 C# → JavaScript compiler.
Where the Connector Recipes cover ingesting data into a workspace, these recipes cover putting a custom UI on top of one.
All ten recipes live inside a single front-end project — FrontEnd.Recipes — so they build together and can be deployed as a single bundle.
Recipes are a developer-onboarding tool
Every recipe targets the same shape: a single C# view returned from a registered route, wrapped in a HubStack + HubTitle so it inherits the workspace's standard chrome. The skeleton is identical — only the body changes.
Project layout
FrontEnd.Recipes/
├── FrontEnd.Recipes.csproj
├── h5.json
├── h5.Release.json
└── src/
├── App.cs ← entry: routes + sidebar + HomeView replacement
├── Recipes.cs ← catalog used by App.cs and the landing page
├── RecipesHomeView.cs ← replaces the workspace's default home view
├── API/
│ └── Endpoints.cs ← Mosaik.API.Endpoints.CallAsync wrappers (currently mocked)
├── Schema/
│ └── DTOs.cs ← [ObjectLiteral] DTOs returned by Endpoints.cs
└── Recipes/
├── 01_HelloWorld/
├── 02_SearchArea/
├── 03_Pivot/
├── 04_SegmentedPivot/
├── 05_NodeRenderer/
├── 06_NeighborsGraph/
├── 07_Dashboard/
├── 08_CustomChat/
├── 09_Sidebar/
└── 10_UserPreferences/
Each recipe folder is self-contained — a README.md explaining the idea and a single (or small handful of) .cs files showing the smallest amount of code that makes the feature work.
The shape of a recipe
Every recipe shares the same skeleton:
public sealed class XyzView : IComponent
{
private readonly IComponent _container;
public XyzView(Parameters state)
{
_container = HubStack(HubTitle("Title", "#/recipe/xyz"), DefaultRoutes.Home)
.Section(BuildBody(state), grow: true);
}
private IComponent BuildBody(Parameters state) { /* ... */ }
public HTMLElement Render() => _container.Render();
}
App.cs registers it as a route and adds a SidebarButton for it — both driven from Recipes.cs, so adding an eleventh recipe is a matter of dropping a new entry into RecipeCatalog.All and creating a folder under src/Recipes/.
Prerequisites
A .NET SDK that matches the h5 toolchain bundled in the
.csproj.The h5 compiler as a global dotnet tool:
dotnet tool update --global h5-compilerThe Curiosity CLI if you want to push the front-end to a workspace from the command line:
dotnet tool update --global Curiosity.CLIA Curiosity workspace to connect to. Local workspaces typically run at
http://localhost:8080/.
Running locally
From the repo root:
cd FrontEnd.Recipes
dotnet build
# Serve the compiled bundle against a workspace
curiosity-cli serve \
-s http://localhost:8080 \
-p bin/Debug/netstandard2.0/h5 \
-port 5000
Add the serving URL to the workspace's CORS allow-list:
export MSK_CORS=http://localhost:5000
Then open http://localhost:5000 in a browser. The first thing you should see is the recipe catalog landing page (the replaced HomeView).
Deploying to a workspace
Zip the h5 output folder and upload it via Manage → Interface → Upload Front End, or push it directly with the CLI:
curiosity-cli upload-front-end \
-s http://localhost:8080/ \
-t $CURIOSITY_INTERFACE_TOKEN \
-p bin/Release/netstandard2.0/h5/
Browse recipes
Each card links to a dedicated page with the recipe's purpose, an example excerpt, and the files to copy.
UI building blocks
Search, nodes, and the graph
Dashboards and chat
Navigation and settings
Talking to the workspace
Anywhere a recipe would hit a custom workspace endpoint, the call goes through src/API/Endpoints.cs. Each method has the production-style call commented out and returns hard-coded data so the repo runs without any backend:
public static async Task<DashboardSeriesResponse> GetDashboardSeriesAsync()
{
// return await Mosaik.API.Endpoints.CallAsync<DashboardSeriesResponse>("recipes/dashboard-series");
return new DashboardSeriesResponse { /* canned data */ };
}
DTOs returned by those endpoints live in src/Schema/DTOs.cs and use [ObjectLiteral] so they round-trip cleanly through h5.
Reusing a recipe
Copy the folder
Pick the recipe whose pattern matches what you need; copy the folder under src/Recipes/ to your own project (or to a new folder here).
Rename the view class
Adjust its namespace to your project.
Register the route
Add it in your App.cs — or add an entry to RecipeCatalog.All if you're staying inside this project — the route, sidebar entry, and home-page card all light up automatically.
Wire the data
Replace any call into RecipeEndpoints with a real Mosaik.API.Endpoints.CallAsync<T> to your workspace endpoint.
See also
- Custom Front-Ends — the reference docs for building Tesserae-based UIs on top of Curiosity Workspace.
- Tesserae — the C# component toolkit the recipes use for layout, search, charts, and chat.
- h5 — the C# → JavaScript transpiler that turns the recipes into the bundle the workspace serves.
- Connector Recipes — the data-ingestion counterpart of these recipes.