Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Isomer

@elastic/isomer

isomer n. — one formula, many forms; the same composition rendered to every surface.

npm version CI License: Elastic License 2.0

Isomer turns one typed Composition into React, HTML, SVG, PNG, Slack Block Kit, Markdown, and plain text. It owns the composition contract, the primitive catalog, validation, and rendering. Hosts own data, authorization, routing, and side effects.

Why

A product answers the same question in more than one place: a page, a Slack message, an agent's reply, an image in an email. Each channel usually gets its own renderer, and they drift. Isomer moves the shared part into one document. A host, or an agent handed the pack's JSON Schema and catalog, composes the answer once from a vocabulary of primitives. Isomer validates it and renders it to every channel, degrading through Markdown and plain text so nothing silently disappears.

What is Isomer? tells the whole story: the vocabulary, the two paths a composition arrives by, what happens inside a render, and what a consumer can rely on.

One composition, three ways

The reference pack's title slide is one composition. These are its committed outputs, written by the same test on every run.

The svg surface, rasterized to PNG:

The reference deck's title slide, rendered to PNG through the svg surface

The markdown surface:

# Title slide

## 01 · Primitives

_Reference pack_

## One composition, every surface.

The same spec renders as HTML, markdown, text, Slack, and SVG.

The text surface:

TITLE SLIDE

01 · Primitives

Reference pack
One composition, every surface.
The same spec renders as HTML, markdown, text, Slack, and SVG.

Slack gets a header block and one mrkdwn section, and HTML gets a section.isomer with only the CSS the slide uses. Every output of every example is in the reference pack's examples.

Two ways a composition is made

The product path. Code owns the composition. A team registers a view with defineView: a stable id, the questions it answers, a Zod input schema, and a builder that fetches data and returns a composition. A host requests it by id, and the registry validates the input before the builder runs and the result after. Nothing model-authored touches this path.

The agent path. A model owns the composition. The runtime hands it the authoring context: a JSON Schema projected from the same Zod schemas the validator uses, the catalog with one example per primitive, and the registered views it may request instead. The host parses what comes back, feeds errors back for a retry, and renders only what validates.

A first composition

A primitive is a schema, a catalog entry an agent reads, and one renderer per surface. A pack is a list of primitives. A runtime turns packs into surfaces.

import { definePrimitive, definePrimitivePack, z } from '@elastic/isomer-sdk';
import { createIsomerRuntime } from '@elastic/isomer-runtime';

const metric = definePrimitive({
  type: 'metric',
  schema: z.object({ type: z.literal('metric'), label: z.string(), value: z.string() }),
  catalog: {
    type: 'metric',
    purpose: 'State one measured value.',
    useWhen: ['A single number answers the question.'],
    avoidWhen: ['Several values belong together.'],
    example: { type: 'metric', label: 'Error rate', value: '0.4%' },
  },
  examples: [{ type: 'metric', label: 'Error rate', value: '0.4%' }],
  renderers: {
    react: (node) => `${node.label}: ${node.value}`,
    text: (node) => `${node.label}: ${node.value}`,
    markdown: (node) => `**${node.label}**: ${node.value}`,
  },
});

const runtime = createIsomerRuntime({
  packs: [definePrimitivePack({ id: 'ops', primitives: [metric] })],
});

const composition = {
  type: 'view',
  title: 'Checkout',
  body: [
    { type: 'metric', label: 'Error rate', value: '0.4%' },
    { type: 'metric', label: 'P99 latency', value: '210 ms' },
  ],
};

runtime.validate(composition); // { valid: true, errors: [], warnings: [] }
runtime.surfaces.text.render(composition);
runtime.surfaces.markdown.render(composition);
runtime.surfaces.slack.render(composition).blocks;
runtime.surfaces.html.render(composition).html;
runtime.getAuthoringContext(); // { schema, primitives, views, … } for an agent

Slack gets its blocks through the Markdown fallback, because the pack wrote no Slack renderer. Supply a frame and the svg surface appears, ready for a rasterizer. The html surface reports validation findings on its result; text, markdown, slack, and svg throw on an invalid composition by default; react never validates.

Which package

You want to Start with
Render compositions in a host: a Kibana plugin, a Slack bot, an MCP server @elastic/isomer-runtime, then its quick start
Write primitives, a theme, or a frame @elastic/isomer-sdk, then its quick start
Copy a working pack @elastic/isomer-primitives-slides, the in-repo reference pack
Turn the svg surface into PNG @elastic/isomer-image-takumi
Score what a model composes from your pack @elastic/isomer-evals

Every package publishes together at one version: the two a host installs, the reference pack to copy from, a host-side rasterizer, and a harness a pack author runs against their own runtime.

Development

corepack enable
pnpm install
pnpm verify

pnpm verify is the full local gate, and CI runs the same command. CONTRIBUTING.md lists what it checks, and AGENTS.md holds the conventions and invariants, written for a human contributor and a coding agent alike.

License

License: Elastic License 2.0

Source available under the Elastic License 2.0 (SPDX: Elastic-2.0). See LICENSE.txt.

About

A schema-driven runtime for authoring views — by agents or humans — rendered to React, HTML, SVG, PNG, Slack Block Kit, Markdown, and plain text.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages