
Native Mermaid 12.0.0 semantics translated and rendered on Compose Canvas, supporting all 33 diagram families with deterministic SceneGraph, extensive visual-parity testing, themes, and WebView-free rendering.
English · 简体中文
Native Mermaid rendering for Kotlin and Compose Multiplatform.
Mermaid 12.0.0 semantics translated to Kotlin and rendered with Compose Canvas.
Live Web demo · 8,448-case independent-scenario visual report · Full stability report · 33-diagram roadmap · Integration
[!IMPORTANT] CMP Mermaid implements all 33 official diagram families from Mermaid
12.0.0. Swimlanes has been revalidated after a direct upstream translation: its classic-look production, 256-case visual, and per-edge topology gates are current. The overall Mermaid12.0.0contract remains not Stable because Architecture's legalrandomize: truepath and legallook: handDrawninput return documentedMermaidError.UnsupportedFeatureresults, and seven detail cases remain under review: five Architecture and two Kanban. The full JVM and Wasm core suites pass.The current 8,448-case Native/Official independent-scenario visual report gives every family 256 real, label-normalized Mermaid sources. Flowchart retains its dedicated coverage corpus; the other 32 families use the complete 256-combination matrix of eight family-specific capability axes. Source, duplicate, detail, geometry, and 528 contact-sheet gates preserve the result. The 441 hand-authored production scenarios and 8,448 text/layout stress inputs remain separate evidence layers.
CMP Mermaid is designed for applications that render many diagrams without a
WebView per diagram. The production path does not embed Mermaid.js and does not
include a network client or require android.permission.INTERNET: parsing,
diagram state, layout preparation, SceneGraph generation, and final Compose
Canvas painting are owned by the multiplatform libraries.
All 33 implemented families retain repository-controlled tests and corpus data, published Native/Official captures, and passing replacement detail and geometry gates.
| Evidence | Result |
|---|---|
| Official Mermaid diagram families | 33 |
| Implemented diagram families | 33/33 |
| Translation pending | Architecture randomize: true spectral/Matrix/SVD path; non-default packing, tiling, radial, and bendpoint branches remain mapped unsupported |
| Flowchart per-edge topology | 256 pass, 0 fail |
| Independent production scenarios | 441 Native/Official pairs |
| Declared capability coverage | 738/738 |
| Independent-scenario visual matrix | 8,448 Native/Official pairs; Flowchart has its dedicated 256-case corpus and every other family has all 256 combinations of eight capability axes |
| Coverage hard gate | Every family has 256/256 label-normalized sources; non-Flowchart axes are balanced 128/128, pairwise balanced 64/64/64/64, and each axis changes all 128 paired sources |
| Duplicate hard gate | Every family has 256/256 unique blueprints, normalized semantics, and label-normalized sources; rendered manifest/PNG uniqueness is diagnostic because distinct legal inputs can render equivalently |
| Text/layout stress inputs | 8,448 byte-distinct inputs derived from the 441 production scenarios; tracked separately and not counted as structural coverage |
| Native/Official captures | 16,896 independent-scenario screenshots plus 882 independent-corpus and 16,896 malformed-source screenshots |
| Source-mutation parity | 8,448/8,448 Official accept/reject outcomes matched: 2,156 accepted and 6,292 rejected; every Native rejection was CONTENT_ERROR; 0 crashes or timeouts |
| Independent-scenario detail audit | 33 families: 8,441 pass, 7 review, 0 fail |
| Automated visual geometry | 8,448/8,448 pairs: 0 failure, 0 review findings |
| Deterministic SceneGraph replay | 441 passed, 0 mismatches |
| Built-in theme matrix | 363/363 |
| Separate generated Native stress inputs | 7,936 retained historical baseline |
| Current 0.1.21 JVM tests | Core: 1,123 passed, 0 failed; Compose: 75 passed, 0 failed |
| Current Jison table equivalence | 12 families, 1,611 states and 20,857 entries match the official JavaScript tables, including key order |
| Current container-width audit | 2 families, 3 unique sources, 9 configuration scenarios, 18 screenshots and 3 contact sheets; 0 Pass / 9 Review / 0 Fail |
| Current 0.1.21 Wasm tests | Core: 1,109 passed, 0 failed; Compose: 62 passed, 0 failed; debug UI: historical 9 passed, 0 failed |
| Current 0.1.21 iOS Simulator Arm64 tests | Core: 1,109 passed, 0 failed; Compose: 76 passed, 0 failed |
| Current SVG rectangle / text-content audit | 79 audit tests passed; one rectangle reproduction and 13 fresh Class sources; genuine occlusion differences remain failures |
| Current Class terminal audit | 13 sources, 26 screenshots, one contact sheet; detail/geometry/topology each pass 13; overall 13 Review for text/node and absolute endpoint differences |
| Core production soak | Historical 415-case baseline: 2,075 renders, 674ms total, 1ms P95, 63,968 bytes retained heap |
| Physical-device runtime matrix | Kotlin 2.3.20 Android 8/8, Kotlin 1.7.21 Android 8/8, and iOS 6/6 passed; 9,702 corpus renders; 198 reviewed sentinels plus 22 completion screenshots; 0 crashes or Android ANRs |
| Runtime load matrix | All three physical-device tracks passed all 441 cases; Web retains the prior 397-scenario baseline; iOS Simulator and Desktop retain the prior 236-scenario baseline |
| Evidence document | What it contains |
|---|---|
| Full diagram roadmap | Official 33-family inventory and current family-gate state |
| Stability test report | Current decision, visual evidence, tests, soak metrics, runtime load evidence, and reproduction steps |
| 0.1.21 parser table size report | Same-consumer iOS measurements: framework-attributed file-backed symbols 38.86 MB → 35.24 MB; parser tables 5.20 MB → 1.57 MB |
| 0.1.20 edge-label repair | Final SVG-path label checks and upstream polyline midpoint semantics; unchanged 32-source evidence captured at 0.1.19 |
| SVG rectangle occlusion audit | Recognizes Official's filled rectangle paths and preserves matching label occlusion; separate one-source reproduction |
| 0.1.20 Class terminal repair | Full upstream terminal calculation, original occlusion and actual HTML text coverage; 13 fresh source-bound pairs |
| 0.1.18 container-width repair | Fresh Gantt parent-width, rounded-coordinate and label-side checks; same-config Mindmap paint and topology, with remaining visual Review findings |
| All 8,448 Native/Official independent scenarios | 528 paged contact sheets, with 16 different same-source scenarios per page |
| Source-mutation Native/Official evidence | 8,448 AI-like mutations from byte-distinct stress bases derived from 441 structural scenarios, 16,896 screenshots, and 528 comparison sheets |
| Android physical-device report | Separate Kotlin 2.3.20 and Kotlin 1.7.21 matrices across Android 9-16 |
| iOS physical-device report | Six-device iOS 14.3-26.0 matrix with complete 441-case loads |
| Production capability matrix | The 738 independently exercised capabilities |
| Production readiness | Code-level Stable criteria, resource budgets, and integration guidance |
| Quality Gate | Current automated JVM, build, publication, security, APK, visual, and Web load results |
| Full Visual Parity | Weekly/manual capture and detail enforcement for all 33 families |
| Full Invalid Source Matrix | Weekly/manual 33 × 256 Native/Official malformed-source safety matrix |
All fresh Swimlanes translation, topology, visual, JVM, Wasm, production
isolation, and publication gates have completed. The refreshed Flowchart
matrix has 107 unique graph topologies and passes all 256 per-edge routing
cases. Overall Mermaid 12.0.0 support remains not Stable until the
Architecture gaps, seven detail reviews, and legal RoughJS-backed unsupported
handDrawn look are resolved, and the remaining formula stages are translated
and revalidated.
A legal feature that cannot be represented faithfully returns
MermaidError.UnsupportedFeature instead of silently drawing a misleading
approximation. An explicitly documented non-semantic fallback, such as
plain-text formula source, returns MermaidDiagnostic.UnsupportedFeature in
the successful MermaidScene.
The comparisons below use the same Mermaid source, theme, layout mode, and fixed viewport. The goal is equivalent meaning and comparable visual quality, not pixel-identical browser output; platform font metrics may differ.
Flowchart: multi-region failover
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
XY Chart: mixed bar and line series
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
State Diagram: labels, loops, branches, and terminal states
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
The current published report contains 441 independent production comparisons plus 8,448 independent-scenario visual cases. A separate 8,448-input text/layout stress corpus remains available for wrapping and layout-pressure regressions: open all 528 independent-scenario visual-evidence pages.
| Diagram | Status | Production cases | Main coverage | Details |
|---|---|---|---|---|
| Flowchart | Detail and topology gates passed | 14 | Jison/FlowDB, Dagre, shapes, links, Markdown/HTML labels; topology 256 pass / 0 fail | Compatibility |
| XY Chart | Detail gate passed | 13 | Jison/XY DB, D3 scales and ticks, bar/line plots, labels | Compatibility |
| Quadrant Chart | Detail gate passed | 13 | Axes, quadrants, points, classes, direct styles, themes | Compatibility |
| Timeline | Detail gate passed | 13 | LR/TD layouts, sections, periods, events, color scales, themes | Compatibility |
| Kanban | Detail gate passed | 13 | Sections, tasks, metadata, priorities, ticket links, themes | Compatibility |
| Sequence | Detail gate passed | 14 | Actors, 26 message forms, notes, activations, control regions | Compatibility |
| Class | Detail gate passed | 13 | Compartments, generics, namespaces, relations, Dagre | Compatibility |
| State | Detail gate passed | 13 | Composite states, concurrency, notes, forks/joins, Dagre | Compatibility |
| Entity Relationship | Detail gate passed | 13 | Attributes, cardinalities, relationships, nested subgraphs | Compatibility |
| Gantt | Detail gate passed | 13 | Dates, dependencies, exclusions, milestones, D3-style ticks | Compatibility |
| Pie | Detail gate passed | 13 | Langium grammar, D3 angles, donut, legends, palettes | Compatibility |
| User Journey | Detail gate passed | 13 | Sections, scores, actors, satisfaction faces, text strategies | Compatibility |
| Requirement | Detail gate passed | 13 | SysML types and fields, elements, seven relationships, Dagre, styling | Compatibility |
| Git Graph | Detail gate passed | 13 | Langium grammar, branches, merges, cherry-picks, orientations, themes | Compatibility |
| Mindmap | Detail gate passed | 13 | Jison/Mindmap DB, CoSE-Bilkent, Dagre, tidy tree, shapes, themes | Compatibility |
| Packet | Detail gate passed | 13 | Langium grammar, explicit and counted fields, row splitting, fixed-grid rendering | Compatibility |
| Radar | Detail gate passed | 13 | Langium grammar, axes, curves, graticules, legends, themes | Compatibility |
| Sankey | Detail gate passed | 13 | CSV grammar, D3 Sankey layout, alignments, value labels, link and node colors | Compatibility |
| Treemap | Detail gate passed | 13 | Langium grammar, D3 hierarchy and squarify layout, classes, values, responsive sizing | Compatibility |
| Venn | Detail gate passed | 13 | Jison grammar, Venn.js/fmin optimization, weighted overlaps, styles, text nodes | Compatibility |
| Ishikawa | Detail gate passed | 13 | Jison indentation grammar, alternating recursive branches, fish-head geometry, wrapping | Compatibility |
| Cynefin | Detail gate passed | 13 | Five domains, deterministic boundaries, confusion overflow, transitions, themes | Compatibility |
| Event Modeling | Detail gate passed | 13 | Langium grammar, frames, swimlanes, data, relations, validation, themes | Compatibility |
| Agentflow | Detail gate passed | 13 | Jison grammar, typed nodes and edges, nested/global/collapsed flows, connectors, metadata, Dagre | Compatibility |
| Block | Detail gate passed | 13 | Jison grammar, grids, spans, composites, shapes, block arrows, links, classes, styles | Compatibility |
| Swimlanes | Revalidated; handDrawn unsupported | 13 | Direct upstream lane-aware Sugiyama translation, orthogonal routing, direction transforms, 256/256 topology pass | Compatibility |
| Architecture | Default layout translated; 5 detail reviews; randomize: true unsupported |
13 | Langium grammar, services, groups, junctions, directional edges, constrained fCoSE layout, icons | Compatibility |
| C4 | Detail gate passed | 13 | Five C4 levels, nested boundaries, deployment nodes, relation variants, styles, and configuration | Compatibility |
| Railroad | Detail gate passed | 18 | Railroad IR, EBNF, ABNF, PEG, shared AST, routed grammar paths, styles, and configuration | Compatibility |
| TreeView | Detail gate passed | 13 | Indentation and box-drawing syntax, hierarchy, annotations, descriptions, icons, styles, and configuration | Compatibility |
| Use Case | Detail gate passed | 18 | Actors, boundaries, UML relationships, notes, JSON tables, styles, and configuration | Compatibility |
| Wardley Map | Detail gate passed | 13 | Value chains, sourcing, evolution, pipelines, annotations, and strategic forces | Compatibility |
| ZenUML | Detail gate passed | 13 | Participants, nested calls, replies, groups, fragments, and participant icons | Compatibility |
All 33 implemented types support Mermaid frontmatter, relevant metadata, Unicode, and the relevant theme variables within their documented compatibility boundaries.
Open the live Kotlin/Wasm demo to browse syntax, render the galleries, switch all 11 themes, and compare CMP Native output with the pinned Mermaid.js reference. Every supported diagram type has an editable Playground with Native/Official preview switching. Mindmap can switch among CoSE-Bilkent, Dagre, and tidy-tree layouts.
The official comparison renderer belongs to mermaid-debug-ui only.
mermaid-core and mermaid-compose never use Mermaid.js.
Mermaid source
-> Kotlin preprocessor and translated parser
-> translated diagram database and layout preparation
-> platform-independent MermaidScene
-> Compose Canvas
mermaid-core owns parsing, diagram state, layout adapters, typed errors,
themes, and the platform-independent SceneGraph.mermaid-compose owns Canvas painting, text measurement, assets,
interactions, and pan/zoom behavior.mermaid-debug-ui owns documentation, galleries, Playground, official
comparison, and load-test screens. It is optional and should remain outside
production release variants.sample/* contains thin Android, iOS, Desktop, and Web launchers around the
shared debug UI.The production libraries contain no JavaScript engine or bundled JavaScript
algorithm. Pure Kotlin Dagre is the default unified layout. ELK names and
flowchart-elk are recognized as upstream inputs but return
MermaidError.UnsupportedFeature("ELK layout"); they are never silently
substituted with another layout.
The current publication coordinates are:
Version 0.1.18 makes MermaidRenderOptions.ganttUseWidth nullable so that an
absent value uses Compose parent content width, while every explicit value
still overrides it. Core without a parent keeps the 1200 fallback. Rebuild
consumers against the changed API. The full-family and physical-device
matrices below retain historical evidence; the fresh repair audit is linked
above.
| Consumer | Artifact |
|---|---|
| Current Kotlin Multiplatform | io.github.swithun-liu:mermaid-core:0.1.21 |
| Current Compose Multiplatform | io.github.swithun-liu:mermaid-compose:0.1.21 |
Android with Kotlin 1.7.21
|
io.github.swithun-liu:mermaid-core-android-kotlin17:0.1.21 |
Android Compose with Kotlin 1.7.21
|
io.github.swithun-liu:mermaid-compose-android-kotlin17:0.1.21 |
| iOS binary |
CMPMermaid CocoaPod 0.1.21
|
Current Kotlin Multiplatform projects:
dependencies {
implementation("io.github.swithun-liu:mermaid-compose:0.1.21")
}[!NOTE] The Maven coordinates above are published and resolvable from the configured public repository. CocoaPods distribution remains a separate binary release path.
Android projects pinned to Kotlin 1.7.21 use the isolated Android artifact:
dependencies {
implementation(
"io.github.swithun-liu:mermaid-compose-android-kotlin17:0.1.21",
)
}The Kotlin 1.7.21 artifacts are Android-only, target JVM 1.8, and require
Android API 24 or newer. Their artifact names are intentionally distinct from
the current KMP modules, so a consumer cannot accidentally resolve Kotlin 2.x
metadata.
Android View-based hosts can use the same Compose renderer without compiling Compose source:
val diagramView = CMPMermaidView(context).apply {
setMermaidSource("flowchart LR\n A --> B")
setMermaidContentDescription("Example Mermaid diagram")
setMermaidErrorListener { error ->
reportRenderFailure(error.type, error.message, error.source)
}
}
container.addView(diagramView)CMPMermaidView is available from both the current Android target and the
Kotlin 1.7.21 Android artifact.
iOS projects can consume the precompiled static XCFramework through CocoaPods:
pod 'CMPMermaid', '0.1.21'The binary exposes CMPMermaidViewControllerFactory.makeViewController(...)
to Swift and includes all renderer font resources. It supports iOS device
arm64 and simulator arm64/x86_64 with a deployment target of iOS 14.
CMPMermaidViewControllerFactory().makeViewController(
source: source,
contentDescription: "Mermaid diagram",
onContentSizeChanged: nil,
onError: { error in
reportRenderFailure(error.type, error.message, error.source)
}
)For a source checkout:
dependencies {
implementation(project(":mermaid-compose"))
debugImplementation(project(":mermaid-debug-ui"))
}Basic Compose usage:
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.swithun.cmpmermaid.compose.MermaidDiagram
import com.swithun.cmpmermaid.core.MermaidTheme
import com.swithun.cmpmermaid.core.MermaidThemePreset
@Composable
fun Diagram(source: String) {
MermaidDiagram(
source = source,
modifier = Modifier.fillMaxWidth(),
theme = MermaidTheme.preset(MermaidThemePreset.Default),
contentDescription = "Mermaid diagram",
onError = { error ->
reportRenderFailure(error.type, error.message, error.source)
},
)
}Formula rendering is an optional host extension. CMP Mermaid does not bundle a
formula parser, a platform View, or a native image type. The host first adapts
its platform formula engine to MermaidFormulaRenderer:
import com.swithun.cmpmermaid.compose.MermaidFormulaArtifact
import com.swithun.cmpmermaid.compose.MermaidFormulaError
import com.swithun.cmpmermaid.compose.MermaidFormulaPainter
import com.swithun.cmpmermaid.compose.MermaidFormulaRenderer
import com.swithun.cmpmermaid.compose.MermaidFormulaRequest
import com.swithun.cmpmermaid.compose.MermaidFormulaRenderingMode
import com.swithun.cmpmermaid.core.GMResult
private data class HostFormulaOutput(
val width: Float,
val height: Float,
val baseline: Float,
val accessibilityText: String,
val painter: MermaidFormulaPainter,
)
private interface HostFormulaAdapter {
suspend fun render(
request: MermaidFormulaRequest,
): GMResult<HostFormulaOutput, MermaidFormulaError>
}
private fun HostFormulaAdapter.asMermaidFormulaRenderer(): MermaidFormulaRenderer =
MermaidFormulaRenderer { request ->
when (val result = render(request)) {
is GMResult.Ok -> {
val output = result.value
GMResult.Ok(
MermaidFormulaArtifact(
width = output.width,
height = output.height,
baseline = output.baseline,
accessibilityText = output.accessibilityText,
painter = output.painter,
),
)
}
is GMResult.Err -> GMResult.Err(result.error)
}
}In a KMP host, the concrete HostFormulaAdapter normally lives in
androidMain, iosMain, or the host dependency-injection layer. It may
rasterize the platform result and capture that image in
MermaidFormulaPainter; CMP Mermaid never imports or discovers the platform
formula engine.
The host then injects that renderer into the normal Compose entry point:
val hostFormulaRenderer = hostFormulaAdapter.asMermaidFormulaRenderer()
MermaidDiagram(
source = source,
formulaRenderer = hostFormulaRenderer,
formulaRenderingMode = MermaidFormulaRenderingMode.Automatic,
onFormulaError = { request, error ->
reportFormulaFallback(request.source, error.message)
},
)The adapter contract is:
request.source contains the formula without the surrounding $$
delimiters. The adapter should also honor displayMode, color, and
accessibilityText.maxWidth and fontSize are Mermaid's computed CSS pixels expressed as
scene logical pixels. maxWidth constrains intrinsic formula content; it
does not request a bitmap that fills the complete width.
rasterScale tells a bitmap-backed adapter how many physical pixels to
allocate per logical pixel; MermaidDiagram supplies the current Compose
density automatically.width, height, and baseline use logical pixels and describe
the provider's intrinsic formula layout box, equivalent to KaTeX's
<math> box. They do not include Mermaid's wrapping width or label
background padding. Width and height must be finite and positive; baseline
must be finite and within 0..height.render is suspending and may run away from the UI thread. An adapter whose
platform engine requires the main thread must perform that dispatch itself.rasterScale and preserve the content aspect
ratio; Mermaid-specific outer layout remains owned by CMP Mermaid. No
platform View is inserted into the diagram.GMResult.Err(MermaidFormulaError...). Coroutine cancellation and fatal
process errors must continue to propagate.The explicitly supplied host renderer takes precedence over any future built-in
renderer. MermaidFormulaRenderingMode.PlainText bypasses all renderers. A
selected renderer failure falls back directly to the visible formula source;
it does not switch implementations or fail the complete diagram. The shared
HTML-label path supports ordinary text around $$...$$ and multiple formula
blocks, following Mermaid 12.0.0's per-match replacement and CSS flex layout.
Direct HTML inline elements retain their formatting. Formula children nested
inside user HTML, block formatting with margins, Sequence, ZenUML, and Event
Modeling formula stages remain documented unsupported boundaries. Formula
support remains non-Stable; the 28-source composition audit
records current Native/Official findings separately from the main visual corpus.
The error callback receives MermaidRenderErrorInfo, including the original
source passed to the renderer.
CONTENT_ERROR represents structured parse, configuration, resource-limit, or
unsupported-content failures. UNEXPECTED_EXCEPTION represents an ordinary
exception caught inside the render pipeline or Compose drawing boundary.
The Compose surface renders Mermaid.js 12.0.0's standard error diagram while
the callback and onRenderResult retain the detailed typed diagnostic. The
published source-mutation corpus verifies Official accept/reject outcome parity
for all 8,448 mutations. Native rejected inputs remain typed CONTENT_ERROR;
exact diagnostic-message equality is reported separately for 1,798/6,292
paired errors and is not manufactured as a compatibility requirement.
Coroutine cancellation and fatal process errors continue to propagate.
Generate all KMP publications under build/maven-repository:
./gradlew \
:mermaid-core:publishAllPublicationsToBuildRepository \
:mermaid-compose:publishAllPublicationsToBuildRepositoryGenerate the Kotlin 1.7.21 Android artifacts with JDK 11:
./android-legacy-build/gradlew -p android-legacy-build \
assembleRelease \
verifyLegacyPublicationCoordinates \
publishLegacyToReleaseRepositoryGenerate and verify the static iOS binary with JDK 17:
./gradlew :mermaid-compose:podPublishReleaseXCFramework
tools/release/verify-ios-xcframework.shThe Quality Gate builds and verifies the iOS XCFramework once and preserves it
with its exact source commit. Pushing a v* tag then builds the modern KMP and
Kotlin 1.7.21 Android artifacts in parallel while reusing only the successful
verified iOS artifact from the successful main push Quality Gate for that
immutable tag commit. All outputs are joined and verified again before any
public registry is updated.
An interrupted publication keeps its prerelease and verified workflow artifact
for 14 days. Re-run the failed jobs, or manually run the Release workflow
with the same immutable tag. Maven Central and CocoaPods are checked before
each write, so an already-published version is verified and skipped instead of
being uploaded again.
All 11 Mermaid 12.0.0 presets are included:
default, dark, forest, neutral, base, neo, neo-dark, redux,
redux-color, redux-dark, and redux-dark-color.
Business themes can start from a preset with Kotlin copy, or consume
Mermaid-compatible themeVariables through MermaidTheme.withVariables(...).
Invalid external values are returned as GMResult.Err.
val brandTheme = MermaidTheme.preset(MermaidThemePreset.ReduxColor).copy(
background = SceneColor(0xFF101820),
nodeFill = SceneColor(0xFFF2AA4C),
nodeText = SceneColor(0xFF101820),
edge = SceneColor(0xFFF2AA4C),
)Arbitrary themeCSS depends on browser DOM/CSS semantics and returns
MermaidError.UnsupportedFeature. Portable styling uses typed Kotlin theme
objects and MermaidFontFamilyResolver.
CMP Mermaid follows a source-mapped translation workflow rather than reimplementing behavior from screenshots:
Source maps: Flowchart · XY Chart · Quadrant Chart · Timeline · Kanban · Sequence · Class · State · ER · Formula rendering · Gantt · Pie · User Journey · Requirement · Git Graph · Mindmap · Packet · Radar · Sankey · Treemap · Venn · Ishikawa · Cynefin · Event Modeling · Agentflow · Block
Run the JVM and publication gates:
./gradlew \
:mermaid-core:jvmTest \
:mermaid-compose:jvmTest \
verifyPublicationCoordinatesRun the samples:
./gradlew :sample:androidApp:installDebug
./gradlew :sample:desktopApp:run
./gradlew :sample:webApp:wasmJsBrowserDevelopmentRunThe stability test report contains the complete cross-platform build and Native/Official visual reproduction commands.
CMP Mermaid is released under the MIT License. Translated Mermaid behavior and development-only reference assets retain their upstream notices in THIRD_PARTY_NOTICES.md.
English · 简体中文
Native Mermaid rendering for Kotlin and Compose Multiplatform.
Mermaid 12.0.0 semantics translated to Kotlin and rendered with Compose Canvas.
Live Web demo · 8,448-case independent-scenario visual report · Full stability report · 33-diagram roadmap · Integration
[!IMPORTANT] CMP Mermaid implements all 33 official diagram families from Mermaid
12.0.0. Swimlanes has been revalidated after a direct upstream translation: its classic-look production, 256-case visual, and per-edge topology gates are current. The overall Mermaid12.0.0contract remains not Stable because Architecture's legalrandomize: truepath and legallook: handDrawninput return documentedMermaidError.UnsupportedFeatureresults, and seven detail cases remain under review: five Architecture and two Kanban. The full JVM and Wasm core suites pass.The current 8,448-case Native/Official independent-scenario visual report gives every family 256 real, label-normalized Mermaid sources. Flowchart retains its dedicated coverage corpus; the other 32 families use the complete 256-combination matrix of eight family-specific capability axes. Source, duplicate, detail, geometry, and 528 contact-sheet gates preserve the result. The 441 hand-authored production scenarios and 8,448 text/layout stress inputs remain separate evidence layers.
CMP Mermaid is designed for applications that render many diagrams without a
WebView per diagram. The production path does not embed Mermaid.js and does not
include a network client or require android.permission.INTERNET: parsing,
diagram state, layout preparation, SceneGraph generation, and final Compose
Canvas painting are owned by the multiplatform libraries.
All 33 implemented families retain repository-controlled tests and corpus data, published Native/Official captures, and passing replacement detail and geometry gates.
| Evidence | Result |
|---|---|
| Official Mermaid diagram families | 33 |
| Implemented diagram families | 33/33 |
| Translation pending | Architecture randomize: true spectral/Matrix/SVD path; non-default packing, tiling, radial, and bendpoint branches remain mapped unsupported |
| Flowchart per-edge topology | 256 pass, 0 fail |
| Independent production scenarios | 441 Native/Official pairs |
| Declared capability coverage | 738/738 |
| Independent-scenario visual matrix | 8,448 Native/Official pairs; Flowchart has its dedicated 256-case corpus and every other family has all 256 combinations of eight capability axes |
| Coverage hard gate | Every family has 256/256 label-normalized sources; non-Flowchart axes are balanced 128/128, pairwise balanced 64/64/64/64, and each axis changes all 128 paired sources |
| Duplicate hard gate | Every family has 256/256 unique blueprints, normalized semantics, and label-normalized sources; rendered manifest/PNG uniqueness is diagnostic because distinct legal inputs can render equivalently |
| Text/layout stress inputs | 8,448 byte-distinct inputs derived from the 441 production scenarios; tracked separately and not counted as structural coverage |
| Native/Official captures | 16,896 independent-scenario screenshots plus 882 independent-corpus and 16,896 malformed-source screenshots |
| Source-mutation parity | 8,448/8,448 Official accept/reject outcomes matched: 2,156 accepted and 6,292 rejected; every Native rejection was CONTENT_ERROR; 0 crashes or timeouts |
| Independent-scenario detail audit | 33 families: 8,441 pass, 7 review, 0 fail |
| Automated visual geometry | 8,448/8,448 pairs: 0 failure, 0 review findings |
| Deterministic SceneGraph replay | 441 passed, 0 mismatches |
| Built-in theme matrix | 363/363 |
| Separate generated Native stress inputs | 7,936 retained historical baseline |
| Current 0.1.21 JVM tests | Core: 1,123 passed, 0 failed; Compose: 75 passed, 0 failed |
| Current Jison table equivalence | 12 families, 1,611 states and 20,857 entries match the official JavaScript tables, including key order |
| Current container-width audit | 2 families, 3 unique sources, 9 configuration scenarios, 18 screenshots and 3 contact sheets; 0 Pass / 9 Review / 0 Fail |
| Current 0.1.21 Wasm tests | Core: 1,109 passed, 0 failed; Compose: 62 passed, 0 failed; debug UI: historical 9 passed, 0 failed |
| Current 0.1.21 iOS Simulator Arm64 tests | Core: 1,109 passed, 0 failed; Compose: 76 passed, 0 failed |
| Current SVG rectangle / text-content audit | 79 audit tests passed; one rectangle reproduction and 13 fresh Class sources; genuine occlusion differences remain failures |
| Current Class terminal audit | 13 sources, 26 screenshots, one contact sheet; detail/geometry/topology each pass 13; overall 13 Review for text/node and absolute endpoint differences |
| Core production soak | Historical 415-case baseline: 2,075 renders, 674ms total, 1ms P95, 63,968 bytes retained heap |
| Physical-device runtime matrix | Kotlin 2.3.20 Android 8/8, Kotlin 1.7.21 Android 8/8, and iOS 6/6 passed; 9,702 corpus renders; 198 reviewed sentinels plus 22 completion screenshots; 0 crashes or Android ANRs |
| Runtime load matrix | All three physical-device tracks passed all 441 cases; Web retains the prior 397-scenario baseline; iOS Simulator and Desktop retain the prior 236-scenario baseline |
| Evidence document | What it contains |
|---|---|
| Full diagram roadmap | Official 33-family inventory and current family-gate state |
| Stability test report | Current decision, visual evidence, tests, soak metrics, runtime load evidence, and reproduction steps |
| 0.1.21 parser table size report | Same-consumer iOS measurements: framework-attributed file-backed symbols 38.86 MB → 35.24 MB; parser tables 5.20 MB → 1.57 MB |
| 0.1.20 edge-label repair | Final SVG-path label checks and upstream polyline midpoint semantics; unchanged 32-source evidence captured at 0.1.19 |
| SVG rectangle occlusion audit | Recognizes Official's filled rectangle paths and preserves matching label occlusion; separate one-source reproduction |
| 0.1.20 Class terminal repair | Full upstream terminal calculation, original occlusion and actual HTML text coverage; 13 fresh source-bound pairs |
| 0.1.18 container-width repair | Fresh Gantt parent-width, rounded-coordinate and label-side checks; same-config Mindmap paint and topology, with remaining visual Review findings |
| All 8,448 Native/Official independent scenarios | 528 paged contact sheets, with 16 different same-source scenarios per page |
| Source-mutation Native/Official evidence | 8,448 AI-like mutations from byte-distinct stress bases derived from 441 structural scenarios, 16,896 screenshots, and 528 comparison sheets |
| Android physical-device report | Separate Kotlin 2.3.20 and Kotlin 1.7.21 matrices across Android 9-16 |
| iOS physical-device report | Six-device iOS 14.3-26.0 matrix with complete 441-case loads |
| Production capability matrix | The 738 independently exercised capabilities |
| Production readiness | Code-level Stable criteria, resource budgets, and integration guidance |
| Quality Gate | Current automated JVM, build, publication, security, APK, visual, and Web load results |
| Full Visual Parity | Weekly/manual capture and detail enforcement for all 33 families |
| Full Invalid Source Matrix | Weekly/manual 33 × 256 Native/Official malformed-source safety matrix |
All fresh Swimlanes translation, topology, visual, JVM, Wasm, production
isolation, and publication gates have completed. The refreshed Flowchart
matrix has 107 unique graph topologies and passes all 256 per-edge routing
cases. Overall Mermaid 12.0.0 support remains not Stable until the
Architecture gaps, seven detail reviews, and legal RoughJS-backed unsupported
handDrawn look are resolved, and the remaining formula stages are translated
and revalidated.
A legal feature that cannot be represented faithfully returns
MermaidError.UnsupportedFeature instead of silently drawing a misleading
approximation. An explicitly documented non-semantic fallback, such as
plain-text formula source, returns MermaidDiagnostic.UnsupportedFeature in
the successful MermaidScene.
The comparisons below use the same Mermaid source, theme, layout mode, and fixed viewport. The goal is equivalent meaning and comparable visual quality, not pixel-identical browser output; platform font metrics may differ.
Flowchart: multi-region failover
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
XY Chart: mixed bar and line series
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
State Diagram: labels, loops, branches, and terminal states
| CMP Native - Compose Canvas | Official - Mermaid.js 12.0.0
|
|---|---|
![]() |
![]() |
The current published report contains 441 independent production comparisons plus 8,448 independent-scenario visual cases. A separate 8,448-input text/layout stress corpus remains available for wrapping and layout-pressure regressions: open all 528 independent-scenario visual-evidence pages.
| Diagram | Status | Production cases | Main coverage | Details |
|---|---|---|---|---|
| Flowchart | Detail and topology gates passed | 14 | Jison/FlowDB, Dagre, shapes, links, Markdown/HTML labels; topology 256 pass / 0 fail | Compatibility |
| XY Chart | Detail gate passed | 13 | Jison/XY DB, D3 scales and ticks, bar/line plots, labels | Compatibility |
| Quadrant Chart | Detail gate passed | 13 | Axes, quadrants, points, classes, direct styles, themes | Compatibility |
| Timeline | Detail gate passed | 13 | LR/TD layouts, sections, periods, events, color scales, themes | Compatibility |
| Kanban | Detail gate passed | 13 | Sections, tasks, metadata, priorities, ticket links, themes | Compatibility |
| Sequence | Detail gate passed | 14 | Actors, 26 message forms, notes, activations, control regions | Compatibility |
| Class | Detail gate passed | 13 | Compartments, generics, namespaces, relations, Dagre | Compatibility |
| State | Detail gate passed | 13 | Composite states, concurrency, notes, forks/joins, Dagre | Compatibility |
| Entity Relationship | Detail gate passed | 13 | Attributes, cardinalities, relationships, nested subgraphs | Compatibility |
| Gantt | Detail gate passed | 13 | Dates, dependencies, exclusions, milestones, D3-style ticks | Compatibility |
| Pie | Detail gate passed | 13 | Langium grammar, D3 angles, donut, legends, palettes | Compatibility |
| User Journey | Detail gate passed | 13 | Sections, scores, actors, satisfaction faces, text strategies | Compatibility |
| Requirement | Detail gate passed | 13 | SysML types and fields, elements, seven relationships, Dagre, styling | Compatibility |
| Git Graph | Detail gate passed | 13 | Langium grammar, branches, merges, cherry-picks, orientations, themes | Compatibility |
| Mindmap | Detail gate passed | 13 | Jison/Mindmap DB, CoSE-Bilkent, Dagre, tidy tree, shapes, themes | Compatibility |
| Packet | Detail gate passed | 13 | Langium grammar, explicit and counted fields, row splitting, fixed-grid rendering | Compatibility |
| Radar | Detail gate passed | 13 | Langium grammar, axes, curves, graticules, legends, themes | Compatibility |
| Sankey | Detail gate passed | 13 | CSV grammar, D3 Sankey layout, alignments, value labels, link and node colors | Compatibility |
| Treemap | Detail gate passed | 13 | Langium grammar, D3 hierarchy and squarify layout, classes, values, responsive sizing | Compatibility |
| Venn | Detail gate passed | 13 | Jison grammar, Venn.js/fmin optimization, weighted overlaps, styles, text nodes | Compatibility |
| Ishikawa | Detail gate passed | 13 | Jison indentation grammar, alternating recursive branches, fish-head geometry, wrapping | Compatibility |
| Cynefin | Detail gate passed | 13 | Five domains, deterministic boundaries, confusion overflow, transitions, themes | Compatibility |
| Event Modeling | Detail gate passed | 13 | Langium grammar, frames, swimlanes, data, relations, validation, themes | Compatibility |
| Agentflow | Detail gate passed | 13 | Jison grammar, typed nodes and edges, nested/global/collapsed flows, connectors, metadata, Dagre | Compatibility |
| Block | Detail gate passed | 13 | Jison grammar, grids, spans, composites, shapes, block arrows, links, classes, styles | Compatibility |
| Swimlanes | Revalidated; handDrawn unsupported | 13 | Direct upstream lane-aware Sugiyama translation, orthogonal routing, direction transforms, 256/256 topology pass | Compatibility |
| Architecture | Default layout translated; 5 detail reviews; randomize: true unsupported |
13 | Langium grammar, services, groups, junctions, directional edges, constrained fCoSE layout, icons | Compatibility |
| C4 | Detail gate passed | 13 | Five C4 levels, nested boundaries, deployment nodes, relation variants, styles, and configuration | Compatibility |
| Railroad | Detail gate passed | 18 | Railroad IR, EBNF, ABNF, PEG, shared AST, routed grammar paths, styles, and configuration | Compatibility |
| TreeView | Detail gate passed | 13 | Indentation and box-drawing syntax, hierarchy, annotations, descriptions, icons, styles, and configuration | Compatibility |
| Use Case | Detail gate passed | 18 | Actors, boundaries, UML relationships, notes, JSON tables, styles, and configuration | Compatibility |
| Wardley Map | Detail gate passed | 13 | Value chains, sourcing, evolution, pipelines, annotations, and strategic forces | Compatibility |
| ZenUML | Detail gate passed | 13 | Participants, nested calls, replies, groups, fragments, and participant icons | Compatibility |
All 33 implemented types support Mermaid frontmatter, relevant metadata, Unicode, and the relevant theme variables within their documented compatibility boundaries.
Open the live Kotlin/Wasm demo to browse syntax, render the galleries, switch all 11 themes, and compare CMP Native output with the pinned Mermaid.js reference. Every supported diagram type has an editable Playground with Native/Official preview switching. Mindmap can switch among CoSE-Bilkent, Dagre, and tidy-tree layouts.
The official comparison renderer belongs to mermaid-debug-ui only.
mermaid-core and mermaid-compose never use Mermaid.js.
Mermaid source
-> Kotlin preprocessor and translated parser
-> translated diagram database and layout preparation
-> platform-independent MermaidScene
-> Compose Canvas
mermaid-core owns parsing, diagram state, layout adapters, typed errors,
themes, and the platform-independent SceneGraph.mermaid-compose owns Canvas painting, text measurement, assets,
interactions, and pan/zoom behavior.mermaid-debug-ui owns documentation, galleries, Playground, official
comparison, and load-test screens. It is optional and should remain outside
production release variants.sample/* contains thin Android, iOS, Desktop, and Web launchers around the
shared debug UI.The production libraries contain no JavaScript engine or bundled JavaScript
algorithm. Pure Kotlin Dagre is the default unified layout. ELK names and
flowchart-elk are recognized as upstream inputs but return
MermaidError.UnsupportedFeature("ELK layout"); they are never silently
substituted with another layout.
The current publication coordinates are:
Version 0.1.18 makes MermaidRenderOptions.ganttUseWidth nullable so that an
absent value uses Compose parent content width, while every explicit value
still overrides it. Core without a parent keeps the 1200 fallback. Rebuild
consumers against the changed API. The full-family and physical-device
matrices below retain historical evidence; the fresh repair audit is linked
above.
| Consumer | Artifact |
|---|---|
| Current Kotlin Multiplatform | io.github.swithun-liu:mermaid-core:0.1.21 |
| Current Compose Multiplatform | io.github.swithun-liu:mermaid-compose:0.1.21 |
Android with Kotlin 1.7.21
|
io.github.swithun-liu:mermaid-core-android-kotlin17:0.1.21 |
Android Compose with Kotlin 1.7.21
|
io.github.swithun-liu:mermaid-compose-android-kotlin17:0.1.21 |
| iOS binary |
CMPMermaid CocoaPod 0.1.21
|
Current Kotlin Multiplatform projects:
dependencies {
implementation("io.github.swithun-liu:mermaid-compose:0.1.21")
}[!NOTE] The Maven coordinates above are published and resolvable from the configured public repository. CocoaPods distribution remains a separate binary release path.
Android projects pinned to Kotlin 1.7.21 use the isolated Android artifact:
dependencies {
implementation(
"io.github.swithun-liu:mermaid-compose-android-kotlin17:0.1.21",
)
}The Kotlin 1.7.21 artifacts are Android-only, target JVM 1.8, and require
Android API 24 or newer. Their artifact names are intentionally distinct from
the current KMP modules, so a consumer cannot accidentally resolve Kotlin 2.x
metadata.
Android View-based hosts can use the same Compose renderer without compiling Compose source:
val diagramView = CMPMermaidView(context).apply {
setMermaidSource("flowchart LR\n A --> B")
setMermaidContentDescription("Example Mermaid diagram")
setMermaidErrorListener { error ->
reportRenderFailure(error.type, error.message, error.source)
}
}
container.addView(diagramView)CMPMermaidView is available from both the current Android target and the
Kotlin 1.7.21 Android artifact.
iOS projects can consume the precompiled static XCFramework through CocoaPods:
pod 'CMPMermaid', '0.1.21'The binary exposes CMPMermaidViewControllerFactory.makeViewController(...)
to Swift and includes all renderer font resources. It supports iOS device
arm64 and simulator arm64/x86_64 with a deployment target of iOS 14.
CMPMermaidViewControllerFactory().makeViewController(
source: source,
contentDescription: "Mermaid diagram",
onContentSizeChanged: nil,
onError: { error in
reportRenderFailure(error.type, error.message, error.source)
}
)For a source checkout:
dependencies {
implementation(project(":mermaid-compose"))
debugImplementation(project(":mermaid-debug-ui"))
}Basic Compose usage:
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.swithun.cmpmermaid.compose.MermaidDiagram
import com.swithun.cmpmermaid.core.MermaidTheme
import com.swithun.cmpmermaid.core.MermaidThemePreset
@Composable
fun Diagram(source: String) {
MermaidDiagram(
source = source,
modifier = Modifier.fillMaxWidth(),
theme = MermaidTheme.preset(MermaidThemePreset.Default),
contentDescription = "Mermaid diagram",
onError = { error ->
reportRenderFailure(error.type, error.message, error.source)
},
)
}Formula rendering is an optional host extension. CMP Mermaid does not bundle a
formula parser, a platform View, or a native image type. The host first adapts
its platform formula engine to MermaidFormulaRenderer:
import com.swithun.cmpmermaid.compose.MermaidFormulaArtifact
import com.swithun.cmpmermaid.compose.MermaidFormulaError
import com.swithun.cmpmermaid.compose.MermaidFormulaPainter
import com.swithun.cmpmermaid.compose.MermaidFormulaRenderer
import com.swithun.cmpmermaid.compose.MermaidFormulaRequest
import com.swithun.cmpmermaid.compose.MermaidFormulaRenderingMode
import com.swithun.cmpmermaid.core.GMResult
private data class HostFormulaOutput(
val width: Float,
val height: Float,
val baseline: Float,
val accessibilityText: String,
val painter: MermaidFormulaPainter,
)
private interface HostFormulaAdapter {
suspend fun render(
request: MermaidFormulaRequest,
): GMResult<HostFormulaOutput, MermaidFormulaError>
}
private fun HostFormulaAdapter.asMermaidFormulaRenderer(): MermaidFormulaRenderer =
MermaidFormulaRenderer { request ->
when (val result = render(request)) {
is GMResult.Ok -> {
val output = result.value
GMResult.Ok(
MermaidFormulaArtifact(
width = output.width,
height = output.height,
baseline = output.baseline,
accessibilityText = output.accessibilityText,
painter = output.painter,
),
)
}
is GMResult.Err -> GMResult.Err(result.error)
}
}In a KMP host, the concrete HostFormulaAdapter normally lives in
androidMain, iosMain, or the host dependency-injection layer. It may
rasterize the platform result and capture that image in
MermaidFormulaPainter; CMP Mermaid never imports or discovers the platform
formula engine.
The host then injects that renderer into the normal Compose entry point:
val hostFormulaRenderer = hostFormulaAdapter.asMermaidFormulaRenderer()
MermaidDiagram(
source = source,
formulaRenderer = hostFormulaRenderer,
formulaRenderingMode = MermaidFormulaRenderingMode.Automatic,
onFormulaError = { request, error ->
reportFormulaFallback(request.source, error.message)
},
)The adapter contract is:
request.source contains the formula without the surrounding $$
delimiters. The adapter should also honor displayMode, color, and
accessibilityText.maxWidth and fontSize are Mermaid's computed CSS pixels expressed as
scene logical pixels. maxWidth constrains intrinsic formula content; it
does not request a bitmap that fills the complete width.
rasterScale tells a bitmap-backed adapter how many physical pixels to
allocate per logical pixel; MermaidDiagram supplies the current Compose
density automatically.width, height, and baseline use logical pixels and describe
the provider's intrinsic formula layout box, equivalent to KaTeX's
<math> box. They do not include Mermaid's wrapping width or label
background padding. Width and height must be finite and positive; baseline
must be finite and within 0..height.render is suspending and may run away from the UI thread. An adapter whose
platform engine requires the main thread must perform that dispatch itself.rasterScale and preserve the content aspect
ratio; Mermaid-specific outer layout remains owned by CMP Mermaid. No
platform View is inserted into the diagram.GMResult.Err(MermaidFormulaError...). Coroutine cancellation and fatal
process errors must continue to propagate.The explicitly supplied host renderer takes precedence over any future built-in
renderer. MermaidFormulaRenderingMode.PlainText bypasses all renderers. A
selected renderer failure falls back directly to the visible formula source;
it does not switch implementations or fail the complete diagram. The shared
HTML-label path supports ordinary text around $$...$$ and multiple formula
blocks, following Mermaid 12.0.0's per-match replacement and CSS flex layout.
Direct HTML inline elements retain their formatting. Formula children nested
inside user HTML, block formatting with margins, Sequence, ZenUML, and Event
Modeling formula stages remain documented unsupported boundaries. Formula
support remains non-Stable; the 28-source composition audit
records current Native/Official findings separately from the main visual corpus.
The error callback receives MermaidRenderErrorInfo, including the original
source passed to the renderer.
CONTENT_ERROR represents structured parse, configuration, resource-limit, or
unsupported-content failures. UNEXPECTED_EXCEPTION represents an ordinary
exception caught inside the render pipeline or Compose drawing boundary.
The Compose surface renders Mermaid.js 12.0.0's standard error diagram while
the callback and onRenderResult retain the detailed typed diagnostic. The
published source-mutation corpus verifies Official accept/reject outcome parity
for all 8,448 mutations. Native rejected inputs remain typed CONTENT_ERROR;
exact diagnostic-message equality is reported separately for 1,798/6,292
paired errors and is not manufactured as a compatibility requirement.
Coroutine cancellation and fatal process errors continue to propagate.
Generate all KMP publications under build/maven-repository:
./gradlew \
:mermaid-core:publishAllPublicationsToBuildRepository \
:mermaid-compose:publishAllPublicationsToBuildRepositoryGenerate the Kotlin 1.7.21 Android artifacts with JDK 11:
./android-legacy-build/gradlew -p android-legacy-build \
assembleRelease \
verifyLegacyPublicationCoordinates \
publishLegacyToReleaseRepositoryGenerate and verify the static iOS binary with JDK 17:
./gradlew :mermaid-compose:podPublishReleaseXCFramework
tools/release/verify-ios-xcframework.shThe Quality Gate builds and verifies the iOS XCFramework once and preserves it
with its exact source commit. Pushing a v* tag then builds the modern KMP and
Kotlin 1.7.21 Android artifacts in parallel while reusing only the successful
verified iOS artifact from the successful main push Quality Gate for that
immutable tag commit. All outputs are joined and verified again before any
public registry is updated.
An interrupted publication keeps its prerelease and verified workflow artifact
for 14 days. Re-run the failed jobs, or manually run the Release workflow
with the same immutable tag. Maven Central and CocoaPods are checked before
each write, so an already-published version is verified and skipped instead of
being uploaded again.
All 11 Mermaid 12.0.0 presets are included:
default, dark, forest, neutral, base, neo, neo-dark, redux,
redux-color, redux-dark, and redux-dark-color.
Business themes can start from a preset with Kotlin copy, or consume
Mermaid-compatible themeVariables through MermaidTheme.withVariables(...).
Invalid external values are returned as GMResult.Err.
val brandTheme = MermaidTheme.preset(MermaidThemePreset.ReduxColor).copy(
background = SceneColor(0xFF101820),
nodeFill = SceneColor(0xFFF2AA4C),
nodeText = SceneColor(0xFF101820),
edge = SceneColor(0xFFF2AA4C),
)Arbitrary themeCSS depends on browser DOM/CSS semantics and returns
MermaidError.UnsupportedFeature. Portable styling uses typed Kotlin theme
objects and MermaidFontFamilyResolver.
CMP Mermaid follows a source-mapped translation workflow rather than reimplementing behavior from screenshots:
Source maps: Flowchart · XY Chart · Quadrant Chart · Timeline · Kanban · Sequence · Class · State · ER · Formula rendering · Gantt · Pie · User Journey · Requirement · Git Graph · Mindmap · Packet · Radar · Sankey · Treemap · Venn · Ishikawa · Cynefin · Event Modeling · Agentflow · Block
Run the JVM and publication gates:
./gradlew \
:mermaid-core:jvmTest \
:mermaid-compose:jvmTest \
verifyPublicationCoordinatesRun the samples:
./gradlew :sample:androidApp:installDebug
./gradlew :sample:desktopApp:run
./gradlew :sample:webApp:wasmJsBrowserDevelopmentRunThe stability test report contains the complete cross-platform build and Native/Official visual reproduction commands.
CMP Mermaid is released under the MIT License. Translated Mermaid behavior and development-only reference assets retain their upstream notices in THIRD_PARTY_NOTICES.md.