One format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar.
git clone https://github.com/geml-spec/geml && cp geml/*.md ~/.claude/agents/Subagents overview
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo/geml-logo-dark.svg">
<img src="docs/assets/logo/geml-logo-light.svg" alt="GEML" width="340">
</picture>
</p>
# GEML — General Expressive Markup Language
*English | [中文](README_CN.md)*
**One format, two readers.**<br>
People *and* AI agents now co-write the same document.<br>
Legible for people; addressable, verifiable, and versioned for machines.
GEML is plain text — organized by **one typed block for everything**, remembered by a **`.gemlhistory` sidecar**.
[](https://www.npmjs.com/package/@geml/geml)
[](https://github.com/geml-spec/geml/actions/workflows/ci.yml)
[](https://github.com/geml-spec/geml/actions/workflows/geml-check.yml)
[](LICENSE)
[](spec/LICENSE-spec.md)
▶ **[Try GEML in the Playground](https://geml-spec.github.io/geml/playground/)** — edit on the left, rendered on the right, and the build verdict flips the moment a reference breaks. No install.
---
GEML is a markup language for structured documents. A `.geml` file reads as plain text, so you never need a renderer to read it. And instead of a separate mini-syntax for each kind of content, GEML puts everything on one construct: the **typed block**.
```
=== code {#hello lang=python}
print("hi")
===
```
Code is a block. So are tables, diagrams, math, callouts, and document metadata. The shape is the same every time, which makes the format easy to learn and hard to get wrong.
## Why a new format now
Markdown was designed for documents that **people hand-write and people read**. Today the same documents are also written, edited, reviewed, and queried by **AI agents and CI pipelines** — and that shift asks three things of a format that Markdown was never built to give:
- **Predictable structure**, so a model emits valid output instead of guessing among a pile of per-feature special cases.
- **References that can be verified**, so an automated edit that breaks a link fails loudly instead of rotting silently.
- **History that travels with the document**, so a reader — human or agent — can see how and why it changed, offline and with no external service.
GEML is built around those three. The goal wasn't to bolt "AI features" onto a document format. It was to pick a format that is both simpler for people and more dependable for machines.
## What's different about GEML
Plenty of formats do one or two of these. What's unusual about GEML is that one plain-text format does all three:
1. **One primitive for every structured block.** Code, tables, diagrams, math, callouts, metadata — all the same `=== type {…}` typed block. One grammar to learn, one grammar to generate correctly: no per-feature syntax, no HTML fallback.
2. **References checked at build time.** Put an `#id` on any block and reference it anywhere; a dangling reference or a broken cross-document link is a build **error**, not a silent 404. Automated edits can't quietly rot.
3. **Self-contained version history.** A sibling `.gemlhistory` file reconstructs any past revision and rolls the document back — offline, with no git and no service — and it's plain text an agent can read to understand how the document evolved.
For a fuller side-by-side across **Markdown, HTML, CommonMark, AsciiDoc, and Org-mode**, see the [format comparison](docs/COMPARISON.md).
## The format in 5 minutes
### Typed blocks
**One shape, every type.** A block is always `=== type {#id .class key=val}` … `===` — only the `type` (and how its body is read) changes:
```
=== code {lang=python}
print("hi")
===
=== note {.intro}
Parsed prose with *emphasis* and a [[#budget]] reference.
===
=== meta
title = "Budget plan"
===
```
A run of `=` (three or more) opens a block; an equal-length run closes it; longer fences nest inside shorter ones. A block that carries an `#id` can also close with the **labeled fence** `=== #id` — no fence-length counting, which makes long or nested blocks much harder to get wrong. The type decides how the body is read — `raw` (verbatim: `code`, `diagram`, `math`, `table`), `flow` (parsed prose with inline markup: `note`), or `data` (one `key=val` per line: `meta`) — and every block may carry an attribute object `{#id .class key=val}`, where a `.class` is a *semantic* label, never a styling hook. The full inline grammar (emphasis, links, `[[#id]]` auto-references, media, footnotes, inline `$math$`) is in the [spec](spec/GEML-spec.md).
### Tables — two bodies, one model
Write a table visually:
```
=== table {#budget caption="Annual cost"}
| Plan | Months | Rate |
|-------|-------:|-----:|
| Basic | 1 | 30 |
| Pro | 2 | 30 |
===
```
…or as data, with **computed columns** and a **summary row**:
```
=== table {#fy25 format=csv header=1 compute="FY [%.1f] = Q1 + Q2 + Q3 + Q4" summary="Segment = 'Total'; FY [%.1f] = sum(FY)"}
Segment, Q1, Q2, Q3, Q4
Cloud, 8, 10, 12, 14
Platform, 5, 6, 7, 9
Services, 3, 4, 4, 5
===
```
*Both forms describe the same model. The `FY` column and `Total` row are computed at build time:*
| Segment | Q1 | Q2 | Q3 | Q4 | FY |
|-----------|---:|---:|---:|---:|-----:|
| Cloud | 8 | 10 | 12 | 14 | 44.0 |
| Platform | 5 | 6 | 7 | 9 | 27.0 |
| Services | 3 | 4 | 4 | 5 | 16.0 |
| **Total** | | | | | **87.0** |
`compute` runs `+ - * / ( )` per row over columns; `summary` adds a foot row from the aggregates `sum / avg / min / max / count` (with arithmetic over them, e.g. weighted ratios); a trailing `[printf]` sets numeric display.
Tables can also pull their data from an external CSV via `src="regions.csv"`.
### Math
```
=== math {#gauss caption="Gaussian integral"}
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
===
```
$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
### Diagrams & charts — host a DSL, or chart a table
GEML never interprets a diagram body; it routes it to a pluggable renderer (an unknown `format` is a warning, body preserved):
```
=== diagram {#flow format=mermaid caption="Review flow"}
graph LR
A[Draft] --> B{Review} -->|ok| C[Publish]
===
```
```mermaid
graph LR
A[Draft] --> B{Review} -->|ok| C[Publish]
```
A diagram can also **chart a table** — single source of truth, with the column references checked at build time and no data copied:
```
=== diagram {format=geml-chart data=#fy25 type=bar x=Segment y=FY}
===
```
*Drawn from the `#fy25` table above:*
```mermaid
xychart-beta
title "FY by segment"
x-axis [Cloud, Platform, Services]
y-axis "FY"
bar [44, 27, 16]
```
## A gift for programmers — geml-code-graph
To really feel how powerful and flexible a single GEML primitive is, let's try it on a code graph — a familiar but demanding case for programmers:
**your whole codebase's call graph, written as GEML.** `geml codemap build` lays the call graph out as a tree of GEML documents — every method an `#id` block, with `#calls` / `#called-by` edges both ways. The **downstream chain** (what a method calls) for troubleshooting, the **upstream chain** (who calls it) for the blast radius — all visible in a second;

```sh
npm i -g @geml/geml # needs Node 22+
geml codemap build # --root defaults to . : detect languages -> index -> one merged graph in ./.geml-code-graph/
geml codemap serve # opens your browser on the graph
```
> **TS/JS** — zero setup: `build` fetches the scip indexer by itself.
> **Java / C / Python / Go / Kotlin** — one extra download, [Joern](https://docs.joern.io/installation): unzip its release package and pass that folder to build, e.g. `--joern C:\joern\joern-cli` (or put it on PATH and skip the flag).
> Mixed front-end + back-end repo — everything merges into **one graph**.
geml-code-graph is itself a diagram format — one line embeds it in any GEML document (`=== diagram {format=geml-code-graph src=.geml-code-graph/index.geml} ===`), and every code change auto-triggers a rebuild, so the graph never drifts. Scale is no obstacle: the graph is plain-text *data tables* — tens of thousands of files and hundreds of thousands of edges stay instant to open and query (pan across the whole thing and its dense, web-like symmetry is genuinely striking), and you can grep any method name to trace its call chain.
## Next — get hands-on
1. Install the **[browser extension](#ecosystem)**, then open a raw `.geml` link and watch it render — the **[GEML spec itself](https://raw.githubusercontent.com/geml-spec/geml/main/spec/GEML-spec.geml)** (dogfood — the spec is a GEML document, rendered at scale), the **[showcase](https://raw.githubusercontent.com/geml-spec/geml/main/docs/examples/showcase.geml)** (a computed table, four charts, a Mermaid flow, and math), or **[playground/sample.geml](https://raw.githubusercontent.com/geml-spec/geml/main/playground/sample.geml)** for the interactive code-graph.
2. Or write your own right now in the ▶ **[Playground](https://geml-spec.github.io/geml/playground/)** — no install.
3. Then read the **[full spec](spec/GEML-spec.md)** (EN / [中文](spec/GEML-spec_CN.md)) for the whole grammar.
## Why this works for humans and AI
The same shape that makes GEML pleasant to read directly is what makes it reliable under automation:
- **Plain text, no rendering step.** A model reads and writes `.geml` directly. What it sees is the document.
- **One uniform primitive.** There's far less to get wrong when geneWhat people ask about geml
What is geml-spec/geml?
+
geml-spec/geml is subagents for the Claude AI ecosystem. One format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar. It has 1 GitHub stars and was last updated today.
How do I install geml?
+
You can install geml by cloning the repository (https://github.com/geml-spec/geml) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is geml-spec/geml safe to use?
+
geml-spec/geml has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains geml-spec/geml?
+
geml-spec/geml is maintained by geml-spec. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to geml?
+
Yes. On ClaudeWave you can browse similar subagents at /categories/agents, sorted by popularity or recent activity.
Deploy geml to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/geml-spec-geml)<a href="https://claudewave.com/repo/geml-spec-geml"><img src="https://claudewave.com/api/badge/geml-spec-geml" alt="Featured on ClaudeWave: geml-spec/geml" width="320" height="64" /></a>More Subagents
The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
The agent that grows with you
Java 面试 & 后端通用面试指南,覆盖计算机基础、数据库、分布式、高并发、系统设计与 AI 应用开发
Build Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.
The agent engineering platform.
Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.