tomato·bazeldocs v0 · latest
Docs/Reference/Modules/meridian_schemas

meridian_schemas

The framework- and brand-neutral root of the meridian design language: proto contracts (PanelDescriptor + Theme), @meridian/proto-ts, and the WebRenderer seam.

Latest0.24.0
Versions18
CategoryModules & tooling
Compat level1
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/meridian_schemas/
Sourcegithub.com/meridian-ux/meridian-schemas
MODULE.bazelstarlark
bazel_dep(name = "meridian_schemas", version = "0.24.0")

View source & releases on GitHub ↗

The framework- and brand-neutral root of the meridian design language. Every renderer and every emitter depends on this module; it depends on none of them.

It ships three things:

  • The proto contractsmeridian.ui.v1.PanelDescriptor (semantics: which RPC to call, how to map the response into rows/columns/actions, what bespoke panels to host) and meridian.theme.v1.Theme (style). Semantics and style are orthogonal proto layers, so a renderer or a skin can depend on one without the other. See proto/.
  • @savvifi/meridian-proto-ts — the canonical TypeScript surface, generated from the protos via protobuf-es (//bazel:proto_es.bzl). The single source the web renderers and the aion emitter consume.
  • @savvifi/meridian-schemas (the WebRenderer seam) — the framework-neutral mount(container, descriptor, theme, invoker) → { update, unmount } interface plus the host transport/runtime contracts (RpcInvoker, RenderContext). Every web renderer implements it: meridian-web (web-components, reference), meridian-web-react (kit-driven React), and any future web renderer. Because the seam lives here, those renderers depend on meridian-schemas rather than on each other. See src/uiview/.

Language bindings for the non-web renderers (Java/JavaFX, Rust/TUI, Swift/SwiftUI) and the wasm web-components core live in their own renderer repos, each depending back on these protos.

Layering

  aion graph ──emits──▶ PanelDescriptor + Theme  (meridian-schemas)

                   WebRenderer seam (neutral TS)
                    ├── meridian-web        (web-components, reference)
                    ├── meridian-web-react  (React · swappable ComponentKit)
                    ├── meridian-tui · meridian-javafx · meridian-swiftui
                    └── …

Dependency direction is strictly one-way: renderers and emitters → meridian-schemas. The module stays brand- and framework-neutral; brand (a Theme) and framework (the kit/renderer) are supplied by consumers.

Build

bazel build //...        # proto contracts, @savvifi/meridian-proto-ts, the seam

Codegen uses a prebuilt protoc (//bazel:protoc_prebuilt.bzl) so it never compiles protoc from source.

Gates

Two checks run on every PR (.github/workflows/ci.yml). Both exist because the failure they catch has already shipped.

python3 tools/check_versions.py      # published versions move in lockstep
node --test "tools/*.test.mjs"       # the mirror gate still catches divergence

Mirroring meridian.ui.v1

Some repos carry a small hand-maintained copy of a few meridian.ui.v1 messages instead of depending on this module — nav_tree.proto imports nothing but field_behavior precisely so a ~40-line mirror is possible. That is supported. A mirror that silently disagrees with the contract is not: a shipped mirror transposed GetPanelRequest’s field numbers, and because both fields are wire type 2 a canonical client and that mirror parse each other’s tag-1 field with no error and get garbage.

If you maintain a mirror, run the gate in your own CI:

# your mirror -> a descriptor set (any toolchain: protoc, Bazel's proto_library,
# tonic_build's committed FDS — a FileDescriptorSet is the interchange format)
protoc -I proto --descriptor_set_out=mirror.binpb --include_imports \
  meridian/ui/v1/layout_service.proto

node tools/mirror_conformance.mjs \
  --canonical canonical.binpb \
  --mirror    mirror.binpb \
  --allowlist mirror-deviations.json     # optional

Only messages present in both are compared. Exit code is non-zero on divergence.

There are two kinds of mirror, and they want different strictness:

kindflaga missing field means
a deliberate hand-written subset (e.g. a ~40-line nav_tree copy)(default)fine — you don’t use it
a vendored copy of the full tree--require-completedrift, and a silent one

In the second case a missing field is a real defect: proto decoders ignore unknown fields, so a producer that sets Slot.sub_view against a consumer vendored before that field existed gets a slot with no panel and no error. REQUIRED does not save you — field_behavior is documentation only in proto3, and no runtime enforces it. Measured across the vendored trees in this fleet: 11–16 fields behind canonical each, with zero disagreements — stale, never wrong. The hand-written subset mirror had the opposite profile: current, but with two transposed field numbers.

A deliberate divergence is legal but must be written down, which turns a silent landmine into a reviewable line:

{ "deviations": [
    { "message": "meridian.ui.v1.GetPanelRequest",
      "field": "panel_id",
      "reason": "legacy plugin surface returns an opaque bundle envelope" }
] }

"field": "*" waives a whole message.

Conformance#

No gate findings. 17 contested atoms. See how gating works or the full report.

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
aspect_bazel_lib 2.22.5 2.8.1 ×1
aspect_rules_js 3.1.2 2.1.3 ×1
bazel_lib 3.2.2 3.0.0 ×12
bazel_skylib 1.8.2 1.9.0 ×2
gawk 5.3.2.bcr.3 5.3.2.bcr.1 ×12
jq.bzl 0.4.0 0.1.0 ×12
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
package_metadata 0.0.2 0.0.5 ×3
protobuf 33.4 34.0.bcr.1 ×2
rules_jvm_external 6.7 6.8 ×4
rules_nodejs 6.7.4 6.3.0 ×16.7.3 ×1
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
tar.bzl 0.10.4 0.5.1 ×110.6.0 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1
yq.bzl 0.3.4 0.1.1 ×12

Dependencies#

meridian_schemas in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

aspect_rules_js3.1.2aspect_rules_ts3.8.9rules_nodejs6.7.4bazel_skylib1.8.2rules_proto7.1.0protobuf33.4googleapis0.0.0-20260422-20ac242a

Used by (3 in the registry)

Versions#

18 published versions, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.24.0 latest 6IC+Miutvgkr464L… tag archive ↗
0.23.0 ieqo3IpEpD5tN7J/… tag archive ↗
0.22.0 9k0sL+0YO/1KyBK4… tag archive ↗
0.21.0 6/OuMMQmvueA+66K… tag archive ↗
0.20.0 8Jf3Tf26g2RyRVRe… tag archive ↗
0.19.0 r47GttPi87u5R+KF… tag archive ↗
0.18.0 uKmU1DPJDCbXfDC5… tag archive ↗
0.17.0 b9zIiJ80v9cvrPQQ… tag archive ↗
0.16.0 ewKAqDUPQ824ngJn… tag archive ↗
0.15.0 EpOQVvcrwTIIwa/p… tag archive ↗
0.14.0 GfiXTd3oJRqnNtzY… tag archive ↗
0.12.0 LnBUGiJs9xKoOZZs… tag archive ↗
0.6.0 /SMqc92fLtqCVyST… tag archive ↗
0.5.0 ZK4r3SxJ0e4TyM1h… tag archive ↗
0.4.0 /2dSjaH5t/szLsOy… tag archive ↗
0.3.0 UJIGBnjmSH5svRZw… tag archive ↗
0.2.0 s5jOejAH3WUnLI23… tag archive ↗
0.1.0 4J9VMHR4Ha4glsFi… tag archive ↗

← All modules