go-ui is a declarative UI protocol and SDK for describing plugin interfaces as JSON schemas. The Go SDK builds and validates manifests and views; the React SDK validates those schemas and renders them with registered HTML and shadcn components. The UI model is independent of the transport, with an MCP adapter available in go-sdk/mcp.
- Declarative manifests, views, regions, nodes, layouts, data sources, actions, and effects.
- Go builders for composing and validating UI schemas.
- React packages for schema validation, transport, and rendering.
- Default HTML and shadcn component registries, with support for custom components.
- Child layout using
row,cols, andoffsetin a 12-column grid. - JSON Schemas for protocol objects in
schemas/.
| Path | Description |
|---|---|
go-sdk/ui |
Go schema types, builders, validation, and component definitions |
go-sdk/mcp |
Adapter that registers the UI manifest and views as MCP resources |
react-sdk/ui-core |
TypeScript protocol types, validation, and runtime helpers |
react-sdk/ui-transport |
HTTP, WebSocket, and RPC transport helpers |
react-sdk/ui-react |
React renderer, registries, and default components |
example/go |
Go examples for an HTML form and dashboard |
example/react |
Vite app with interactive React examples |
schemas |
JSON Schema documents for protocol entities |
- Go 1.26.8 or newer.
- Node.js and pnpm 12.6.0, as declared by the workspace package manifest.
Run these commands from the repository root. make install installs the pnpm workspace from the lockfile and installs/configures goppy for Go workflows.
| Command | What it runs |
|---|---|
make install |
Frozen pnpm dependency install, goppy@latest installation, and goppy setup-lib |
make lint |
pnpm lint, formatting, formatting check, and goppy lint |
make tests |
pnpm tests and goppy test |
make build |
Build the three npm packages, run pnpm typecheck, and run goppy build --arch=amd64 |
make license |
Run goppy license |
make pre-commit |
Run install, license, lint, build, and tests |
make examples-dev |
Start the React example app with Vite |
make lint runs pnpm format, which can rewrite files. The Go lint and setup workflows can also update generated files. Review git status after running them.
make tests does not build the npm packages. In a clean checkout, run make build before make tests so package exports in dist exist. make npm-publish runs the full build before publishing the packages publicly.
The root Go module is go.osspkg.com/ui. Add it to a Go module with:
go get go.osspkg.com/uiThis example builds a profile view with a card and individually positioned child nodes:
package main
import "go.osspkg.com/ui/go-sdk/ui"
func newProfileApp() (*ui.App, error) {
app := ui.New(
ui.AppID("profile"),
ui.AppTitle("Profile"),
ui.AppVersion("1.0.0"),
)
view := ui.View(
"profile.edit",
ui.Title("Edit profile"),
ui.Content(
ui.HTML(ui.HTMLArticle, "profile-card").Row(1).Cols(8).Offset(2).Children(
ui.HTML(ui.HTMLH1, "heading").Row(1).Cols(12).Prop("text", "Edit profile"),
ui.HTML(ui.HTMLInput, "name").Row(2).Cols(8).Offset(2).Prop("placeholder", "Ada Lovelace"),
),
),
)
if err := app.AddView(view); err != nil {
return nil, err
}
return app, nil
}To expose the manifest and views as MCP resources, register the app with the MCP adapter:
import (
goMCP "go.osspkg.com/mcp"
"go.osspkg.com/ui/go-sdk/ui"
uiMCP "go.osspkg.com/ui/go-sdk/mcp"
)
func registerUI(app *ui.App) error {
server, err := goMCP.New(
goMCP.ServerInfo{Name: "profile", Version: "1.0.0"},
uiMCP.Capabilities(),
)
if err != nil {
return err
}
return uiMCP.Register(server, app)
}The adapter publishes resources; a host that uses the React runtime must separately handle ui.get, data.call, and ui.action. See the dashboard example for sources, actions, and effects.
Install the packages used by your application:
pnpm add @osspkg/ui-core @osspkg/ui-reactRegister the built-in component sets, load the package stylesheet, and render a ViewSchema:
import {
createComponentRegistry,
registerDefaultHTMLComponents,
registerDefaultShadcnComponents,
UIProvider,
ViewRenderer,
} from "@osspkg/ui-react";
import type { ViewSchema } from "@osspkg/ui-core";
import "@osspkg/ui-react/styles.css";
const components = createComponentRegistry();
registerDefaultHTMLComponents(components);
registerDefaultShadcnComponents(components);
const schema: ViewSchema = {
protocolVersion: "1.0",
id: "welcome",
title: "Welcome",
regions: {
"top-header": [],
"left-panel": [],
"right-panel": [],
bottom: [],
content: [
{
id: "welcome-card",
component: "card",
layout: { row: 1, cols: 8, offset: 2 },
children: [
{ id: "title", component: "h1", layout: { row: 1, cols: 12 }, props: { text: "Welcome" } },
{ id: "body", component: "p", layout: { row: 2, cols: 8, offset: 2 }, props: { text: "Rendered from a schema." } },
],
},
],
},
};
export function WelcomeView() {
return (
<UIProvider components={components}>
<ViewRenderer schema={schema} />
</UIProvider>
);
}Nodes with children create their own 12-column grid. Set a child's layout to control its row, width (cols), and horizontal offset; nodes without a layout use the available row. The interactive example demonstrates forms, default registries, and nested layouts.
This project is licensed under the BSD 3-Clause License.