Examples
Live demos rendered through remark-codegloss. Each example below is a standard MDX fenced code block in this page's source — the plugin transforms them into <code-gloss> Web Component instances at build time.
Click any underlined token to expand its annotation. Click a connection arc (or one of its endpoint dots) to see why those annotations are related.
Memoized Fibonacci
A classic memoization pattern. Annotations explain the cache lifecycle, and connections link the table declaration to its lookups.
Event Delegation
A pattern where a single listener on a parent element handles events for multiple children.
Data Flow — Right-side arrows
Connections can render on the right side of the code block via "side": "right", anchored at each line's end rather than in the fixed gutter. Combined with "arcs": { "arrowhead": true }, arcs become explicit flow indicators — the arrow points at the to endpoint, the from endpoint stays a dot.
arrowhead is set per block, not per connection — the example below applies arrowheads to all three arcs, the two left-side ones (q1→q2, q4→q2) as well as the single right-side one (q3→q5).
Popover callouts
Annotation callouts normally render inline — clicking a token expands a row of context directly below its line. For denser docs where vertical expansion would shuffle the page, set callouts.popover: true to present the callout as a floating popover anchored to the click position instead.
Annotation and connection popovers are independent surfaces: a reader can have an annotation popover and an arc popover open at the same time. Inline and popover presentations of the same annotation are mutually exclusive.
Pre-opened callouts (walkthrough style)
For in-doc walkthroughs you can surface a specific annotation or connection on first render via defaultOpen. At most one annotation callout and one connection popover can be pre-opened per block — if multiple are marked, the last one in its array wins (CSS-cascade style).
Minimal — No Annotations
A codegloss block without a following annotations block renders as a plain code viewer with line numbers and a toolbar.
Other usage patterns
The examples above all use the MDX fenced code block syntax with the remark plugin. CodeGloss also works as a direct React component or a vanilla HTML Web Component.
React (direct)
Import CodeGloss from @codegloss/react and pass props directly — no remark plugin or MDX needed:
import { CodeGloss } from '@codegloss/react';
export function Example() {
return (
<CodeGloss
code={`function greet(name) {
return 'Hello, ' + name;
}`}
lang="js"
filename="greet.js"
annotations={[
{ id: 'a1', token: 'name', line: 0, occurrence: 0,
title: 'Parameter', text: 'The name to greet.' },
]}
connections={[]}
/>
);
}
Vanilla HTML
Drop a <code-gloss> custom element on any page. No build step required:
<script type="module" src="https://unpkg.com/codegloss/dist/index.js"></script>
<code-gloss>
<script type="application/json">
{
"code": "function greet(name) {\n return 'Hello, ' + name;\n}",
"lang": "js",
"filename": "greet.js",
"annotations": [
{ "id": "a1", "token": "name", "line": 0, "occurrence": 0,
"title": "Parameter", "text": "The name to greet." }
]
}
</script>
</code-gloss>
HTML output mode (plain markdown pipelines)
For non-MDX pipelines (marked, markdown-it, remark → rehype → HTML), use the remark plugin with output: 'html'. This emits raw <code-gloss> elements instead of JSX:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import remarkCodegloss from 'codegloss/remark';
const html = await unified()
.use(remarkParse)
.use(remarkCodegloss, { output: 'html' })
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeStringify, { allowDangerousHtml: true })
.process(markdownSource);
Load the runtime on the page so the custom element registers:
<script type="module" src="https://unpkg.com/codegloss/dist/index.js"></script>