Skip to Content

UI

This page covers building custom UI bundles. If you only need to configure which UI a deployment serves, use Providers > UI.

UI bundles are static asset packages. Gestalt serves them under the path prefixes configured in providers.ui.<name>.path. The built-in admin UI at /admin remains available regardless of whether a custom UI bundle is configured.

For local iteration, you can run a source UI bundle directly with the same provider-local commands used for plugins:

gestaltd provider validate --path ./ui gestaltd provider dev --path ./ui

When the UI is part of a plugin/ + sibling ui/ package layout, running gestaltd provider dev from the plugin side also picks up that sibling UI automatically for the local session.

A UI bundle is not a plugin in the executable sense. It contains no server-side code. Gestalt simply serves the static files from the asset root directory. The bundle talks to Gestalt through the same HTTP API and MCP endpoints that any other client would use.

Manifest

The Default UI manifest declares spec.assetRoot, which points to the directory containing the built static assets. The source field identifies the provider in the registry.

kind: ui source: github.com/valon-technologies/gestalt-providers/ui/default version: 0.0.1 displayName: Default UI description: Default Gestalt UI bundle. release: build: command: - sh - ./build.sh spec: assetRoot: out routes: - path: / allowedRoles: [viewer, admin] - path: /admin/* allowedRoles: [admin]

The assetRoot path is relative to the manifest file. It should contain the output of your frontend build (typically an index.html and accompanying JS, CSS, and image files).

spec.routes is optional unless a deployment binds the UI to providers.ui.<name>.authorizationPolicy. In that case, Gestalt uses these route rules to enforce role-based access before serving the mounted route or its static assets. At least one route must cover /, and every route must declare non-empty allowedRoles.

Build step

If your UI needs a build step before packaging, use release.build to run it automatically during gestaltd provider release. This runs before source-manifest preparation, so the built assets are included in the release archive.

The Default UI uses a shell script that runs npm ci && npm run build to produce the static output:

kind: ui source: github.com/valon-technologies/gestalt-providers/ui/default version: 0.0.1 release: build: command: - npm - run - build spec: assetRoot: out

The command runs relative to the manifest directory. After the build completes, Gestalt packages everything under assetRoot into the release archive. You can use any build tool here — npm run build, vite build, next build && next export — as long as it writes output to the directory specified in assetRoot.

Configuring a UI bundle

Reference a UI bundle in the providers.ui map of the server config. During development, point at the source manifest:

providers: ui: dashboard: source: ./web-default/manifest.yaml path: /dashboard authorizationPolicy: dashboard_users

For production, reference a published release metadata URL:

providers: ui: dashboard: source: https://artifacts.example.com/ui/default/v0.0.1/provider-release.yaml path: /dashboard authorizationPolicy: dashboard_users

When a config references a published UI bundle, run gestaltd init to resolve and prepare it. This writes lock state to gestalt.lock.json and extracts the assets under .gestaltd/. After init, gestaltd serve --locked serves the locked UI bundle from its configured path prefix. If the prepared UI files are already present, Gestalt uses them directly; if they are missing, Gestalt can materialize them from the lockfile at startup.

If providers.ui is omitted entirely, Gestalt runs headless with no public UI bundles.

The admin UI

The built-in admin UI is always served at /admin, regardless of whether a custom UI bundle is configured. It provides a management interface for users, plugins, connections, and API tokens. Mounted bundles own only their configured public prefixes.

Release

UI bundles use the same release system as provider packages:

gestaltd provider release --version 0.0.1

Run this from the directory containing the manifest. If release.build is defined, the build command runs first, then Gestalt packages the manifest and the asset root into a release archive. See Releasing for details on release archives, tag resolution, and prepared state.

  • Releasing: release archives, tag resolution, and prepared state
  • Configuration: full server config reference including providers.ui