mermaid-js/mermaid
Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
Healthy across the board
- ✓Last commit today
- ✓5 active contributors
- ✓Distributed ownership (top contributor 43%)
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Small team — 5 top contributors
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Embed this verdict
[](https://repopilot.app/r/mermaid-js/mermaid)Paste into your README — the badge live-updates from the latest cached analysis.
Onboarding doc
Onboarding: mermaid-js/mermaid
Generated by RepoPilot · 2026-05-05 · Source
Verdict
GO — Healthy across the board
- Last commit today
- 5 active contributors
- Distributed ownership (top contributor 43%)
- MIT licensed
- CI configured
- Tests present
- ⚠ Small team — 5 top contributors
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
TL;DR
Mermaid is a JavaScript/TypeScript monorepo that generates diagrams (flowcharts, sequence diagrams, Gantt charts, class diagrams, ER diagrams, Git graphs, and ~20 more types) from a Markdown-like text syntax. It solves the problem of maintaining diagrams as code — text definitions are parsed via Jison-generated parsers and Langium grammars, then rendered to SVG using D3.js and Dagre for layout. Pnpm monorepo: the core library lives in packages/mermaid/ (parser, renderer, diagram definitions), with sibling packages for the live editor, Zenuml support, and other integrations. Build tooling lives in .build/ (esbuild transforms, Jison transformer, Langium code generation) and .esbuild/; diagram-specific logic is split into src/diagrams/<type>/ subdirectories under packages/mermaid/src/.
Who it's for
Developers and technical writers who embed diagrams in GitHub READMEs, Notion, Confluence, or documentation sites without needing separate diagramming tools. Also active OSS contributors adding new diagram types or fixing parser/renderer bugs in TypeScript.
Maturity & risk
Mermaid is a highly mature, production-ready project — it won the JS Open Source Awards in 2019, has millions of weekly npm downloads, and is natively supported in GitHub Markdown. The repo has a full CI pipeline (.github/workflows/build.yml), Cypress visual regression tests via Argos, and an active changeset-based release workflow. Commit activity and the .changeset directory show very recent, high-frequency development.
Low risk for consumers — it is widely depended upon by GitHub, GitLab, Notion, and others, making abandonment unlikely. Contributor risk is moderate: the Jison parser files (.jison in Yacc at 178k lines) are complex legacy artifacts that are hard to modify safely, and the migration to Langium grammars is incomplete. The monorepo uses pnpm workspaces and a specific packageManager version (pnpm@10.30.3 with a pinned sha512 hash), so version mismatches cause hard-to-debug install failures.
Active areas of work
Active work visible in .changeset entries includes: adding Wardley Maps diagram type, Event Modeling diagram, nested namespaces in class diagrams, TreeView/FileTree enhancements, Sankey apple-style theming, architecture diagram deterministic layout fixes, and numerous parser bug fixes (ER diagram single-identifier, sequence diagram missing-space hang, ZenUML SVG renderer). Quadrant chart Unicode support and Gantt duration format documentation are also in flight.
Get running
git clone https://github.com/mermaid-js/mermaid.git && cd mermaid && corepack enable && pnpm install && pnpm dev
Daily commands: pnpm dev # starts esbuild dev server (tsx .esbuild/server.ts) pnpm dev:vite # alternative Vite-based server pnpm build # full build: esbuild + TypeScript declarations pnpm test # Vitest unit tests pnpm cypress:open # interactive visual regression tests
Map of the codebase
.build/common.ts— Defines shared build configuration and utilities used across all build scripts — understanding this is prerequisite to understanding how packages are compiled..esbuild/build.ts— Main esbuild entry point that orchestrates bundling of all mermaid packages; controls output formats, entry points, and plugin composition..esbuild/jisonPlugin.ts— Custom esbuild plugin that transforms Jison grammar files into JavaScript parsers at build time — central to how diagram syntax parsers are generated..build/generateLangium.ts— Drives Langium grammar compilation for newer diagram types, representing the migration path away from Jison toward a typed grammar system..changeset/config.json— Changesets configuration controlling the versioning and release strategy for all packages in this monorepo..esbuild/util.ts— Shared utilities for the esbuild pipeline including file resolution and transformation helpers relied on by all build plugins..build/types.ts— Central TypeScript type definitions shared across the build toolchain, defining the contract between build scripts and package configurations.
How to make changes
Add a new diagram type
- Create a new Jison grammar file defining the diagram syntax, following the pattern of existing grammars (
.esbuild/jisonPlugin.ts) - Register the grammar transformation in the build pipeline so it gets compiled to a JS parser (
.build/jisonTransformer.ts) - Add a changeset entry documenting the new diagram type for versioning (
.changeset/event-modeling-diagram.md) - Add the new diagram package to the monorepo build entry points (
.esbuild/build.ts)
Add a new diagram type using Langium (modern approach)
- Define the Langium grammar file for the new diagram syntax (
.build/generateLangium.ts) - Register the new grammar in the Langium generation script so it produces typed AST classes (
.build/common.ts) - Wire the new package into the main esbuild bundle (
.esbuild/build.ts)
Add a new build plugin (e.g. asset inlining)
- Create a new esbuild plugin file following the pattern of existing plugins (
.esbuild/jsonSchemaPlugin.ts) - Register the plugin in the main build script so it is applied during bundling (
.esbuild/build.ts) - Add any shared utilities needed by the plugin (
.esbuild/util.ts)
Ship a release for a package
- Create a changeset file describing the change type (major/minor/patch) and affected packages (
.changeset/README.md) - Ensure the release workflow is configured to pick up the changeset and publish to npm (
.github/workflows/release.yml) - Verify changesets config includes the package and correct base branch (
.changeset/config.json)
Why these technologies
- esbuild — Extremely fast JavaScript bundler enabling sub-second incremental builds for a large monorepo with many diagram packages and grammar files.
- Jison — LALR(1) parser generator that allows diagram syntax grammars to be defined declaratively and compiled to efficient JavaScript parsers.
- Langium — Modern, TypeScript-native language workbench replacing Jison for newer diagram types, providing typed ASTs, better tooling, and VS Code language server support.
- pnpm workspaces — Efficient monorepo package management with strict dependency isolation and fast installs via hard-linking, critical for a repo with many sub-packages.
- Changesets — Enables independent versioning of multiple packages in the monorepo with automated changelog generation and npm publish coordination.
- TypeScript — Provides type safety across diagram APIs, renderer interfaces, and parser contracts, reducing integration bugs between diagram modules.
Trade-offs already made
-
Dual parser strategy: Jison for legacy diagrams, Langium for new ones
- Why: Allows gradual migration to a superior toolchain without breaking existing diagram syntax or requiring a big-bang rewrite.
- Consequence: Build pipeline complexity: two grammar compilation systems must be maintained, tested, and kept in sync with the bundler.
-
Monorepo with pnpm workspaces
- Why: Co-locates all diagram implementations, shared utilities, and the core mermaid library for atomic changes and unified CI.
- Consequence: Developers must understand pnpm workspace protocols and changeset discipline; global installs and link resolution can surprise newcomers.
-
Grammar-driven diagram parsing (no handwritten recursive descent parsers)
- Why: Declarative grammars are easier to read, modify, and validate; syntax changes don't require rewriting parser logic.
- Consequence: Grammar compilation is a build-time step adding latency; grammar debugging requires understanding Jison/Langium tooling, not just JavaScript.
-
Client-side rendering in the browser
- Why: Mermaid is designed as a library that runs in any HTML page without a server, maximizing portability and integration flexibility.
- Consequence: Large bundle sizes (multiple diagram parsers + renderers) and no server-side caching of rendered SVGs; performance is limited by the host browser.
Non-goals (don't propose these)
- Does not provide a backend server or API — all parsing and rendering is client-side
- Does not store or persist diagrams — stateless library only
- Does not handle user authentication or multi-user collaboration
- Does not produce raster image output natively — outputs SVG only
- Does not provide a drag-and-drop visual diagram editor — text-only input
- Does not support real-time collaborative editing of diagram source
Traps & gotchas
- The packageManager field pins pnpm to an exact sha512 hash — use
corepack enableand let corepack handle the version, otherwise install silently uses the wrong pnpm. 2) Jison grammar files must be compiled before TypeScript; runningtscdirectly without the build pipeline fails. 3) Cypress visual tests require a running dev server on a specific port —pnpm dev:coveragesets VITE_COVERAGE=true and must be running beforepnpm cypress. 4) Adding a diagram type requires registering it in the diagram-api AND adding a lazy-loader — forgetting the lazy-loader causes silent failures in the browser bundle.
Architecture
Concepts to learn
- Jison LALR Parser Generation — Mermaid's diagram grammars (.jison files) are compiled by Jison into JavaScript parsers at build time — understanding LALR(1) parsing explains why grammar conflicts cause cryptic build errors
- Langium Grammar Language — Newer diagram types use Langium DSL for grammar definition, generating TypeScript AST types and parsers — the project is migrating toward this from Jison
- Dagre Graph Layout Algorithm — Mermaid uses Dagre to automatically compute x/y positions of nodes in flowcharts and class diagrams — understanding its layered layout approach explains why complex graphs sometimes have unexpected shapes
- Changeset-Based Versioning — The repo uses @changesets/cli to manage versioning across the monorepo — contributors must add a .changeset markdown file with their PR or the release process breaks
- ELK (Eclipse Layout Kernel) — An alternative to Dagre used for more complex diagram layouts (e.g. nested subgraphs) — mermaid supports both engines and choosing the wrong one for a diagram type causes layout artifacts
- SVG foreignObject — Mermaid injects HTML labels into SVG using foreignObject elements — this causes cross-browser inconsistencies and is why some rendering options disable HTML labels entirely
Related repos
plantuml/plantuml— The dominant alternative text-to-diagram tool, JVM-based, serving the same use case of diagram-as-code but with different syntax and a Java runtime requirementmermaid-js/mermaid-live-editor— The official companion live editor app (mermaid.live) that embeds mermaid for real-time preview — closely coupled to this repo's APImermaid-js/mermaid-js.github.io— Documentation site for mermaid, contains usage examples and diagram syntax references that mirror the source diagramsdagrejs/dagre— The directed graph layout engine mermaid uses internally for flowchart and class diagram node positioningd3/d3— The SVG rendering and DOM manipulation library mermaid uses as its core rendering primitive
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for .build/jisonTransformer.ts
The .build/jisonTransformer.ts file is a critical part of the build pipeline that transforms Jison grammar files into parser code. There is also a scripts/jison/lint.mts linting script for Jison files, but no corresponding unit tests for the transformer itself. Since many diagram parsers in mermaid rely on Jison grammars, bugs in this transformer can silently break multiple diagram types. Adding unit tests would catch regressions early and give new contributors confidence when modifying the build pipeline.
- [ ] Read
.build/jisonTransformer.tsto understand its input/output contract (what it receives as grammar source and what it emits) - [ ] Create a test file at
.build/jisonTransformer.test.tsusing Vitest (already used in the repo) - [ ] Add a test case with a minimal valid Jison grammar snippet and assert the transformer output contains expected parser boilerplate
- [ ] Add a test case for an invalid/malformed Jison grammar and assert the transformer throws a descriptive error
- [ ] Add a test case verifying that the transformer preserves specific grammar rules (e.g., token definitions) in its output
- [ ] Run
pnpm lint:jisonand ensure the test file itself passes the linter - [ ] Update the PR description referencing the existing
scripts/jison/lint.mtsto explain the complementary nature of the new tests
Add missing changeset documentation entries for recently added diagram types (Event Modeling, Wardley Maps, Treemap)
The .changeset directory contains several entries referencing new diagram features (event-modeling-diagram.md, add-wardley-maps.md, enhance-treeview-filetree.md, treemap-dark-theme-colors.md) but the main docs structure (visible under packages/mermaid) likely lacks dedicated syntax reference pages or has stub pages for these newer diagram types. A contributor can audit each new diagram's changeset, find the corresponding missing or incomplete documentation page, and flesh out the syntax reference with examples — making these features actually usable by end users.
- [ ] Read
.changeset/event-modeling-diagram.md,.changeset/add-wardley-maps.md,.changeset/enhance-treeview-filetree.md, and.changeset/treemap-dark-theme-colors.mdto understand what each feature adds - [ ] Navigate to
packages/mermaid/src/docs/(or equivalent docs folder) and identify missing or stub documentation pages for each diagram type - [ ] For Event Modeling diagram: create or complete a
eventModeling.mddocs page with syntax BNF/examples, at least 3 realistic diagram code examples - [ ] For Wardley Maps: verify
.changeset/fix-wardley-hyphenated-names.mdfix is documented and add a hyphenated-name example to the existing Wardley Maps docs page - [ ] For Treemap: document the dark theme color behavior change from
.changeset/treemap-dark-theme-colors.mdin the theming configuration docs - [ ] Ensure each new docs page includes a live-editable code block following the pattern of existing diagram docs
- [ ] Run
pnpm --filter mermaid run docs:buildto verify no broken links or build errors
Refactor .build/jsonSchema.ts and .esbuild/jsonSchemaPlugin.ts to share a common schema validation utility
There are two separate files handling JSON Schema concerns: .build/jsonSchema.ts (used during the main build via tsx) and .esbuild/jsonSchemaPlugin.ts (an esbuild plugin). These almost certainly duplicate JSON schema loading, validation, or code-generation logic. Extracting shared logic into a single utility (e.g., .build/jsonSchemaUtils.ts) reduces the risk of the two implementations drifting apart — which has historically caused subtle bugs where dev builds behave differently from production builds in diagram
Good first issues
- Many diagram types in packages/mermaid/src/diagrams/ have minimal or no unit test coverage for their parser edge cases — adding tests for the Gantt parser's duration format handling (referenced in .changeset/docs-gantt-duration-format.md) would be valuable. 2) The .changeset/enhance-treeview-filetree.md suggests active work on TreeView — writing integration tests for the new file tree syntax variations would complement the feature work. 3) Several architecture diagram changesets (.changeset/fix-architecture-console-warnings.md, fix-architecture-deterministic-layout.md) indicate the architecture diagram is undertested — adding Cypress visual snapshots for architecture diagram edge cases would prevent regressions.
Top contributors
- @pbrolin47 — 29 commits
- @ashishjain0512 — 13 commits
- @knsv — 10 commits
- @Felix-Garci — 8 commits
- @tractorjuice — 7 commits
Recent commits
71f9731— Merge pull request #7709 from mermaid-js/chore/e2e-scope-skip-ignorable-files (ashishjain0512)dc52afc— Merge branch 'develop' into chore/e2e-scope-skip-ignorable-files (ashishjain0512)e57282e— fix: make e2e scoping on-by-default so fork PRs benefit (ashishjain0512)36ef39e— Merge pull request #7704 from mermaid-js/chore/e2e-scope-skip-ignorable-files (ashishjain0512)eeb585d— Merge pull request #7527 from notionparallax/feature/treeview-filetree-enhancements (ashishjain0512)0cb8cc8— fix: downgrade @argos-ci/cypress to 6.2.12 to fix missing dist/task.js (ashishjain0512)909933d— fix: add CODEOWNERS to cspell dictionary (ashishjain0512)bea2aeb— chore: skip e2e tests for docs-only and ignorable-file PRs (ashishjain0512)84abc58— Merge pull request #7693 from dull-bird/fix/quadrant-chart-unicode-support (knsv)652cfa5— Merge branch 'develop' into fix/quadrant-chart-unicode-support (dull-bird)
Security observations
- Critical · Container Running as Root (UID 0) —
Dockerfile. The Dockerfile explicitly sets 'USER 0:0', meaning the application runs as the root user inside the container. If an attacker exploits any vulnerability in the application, they would have full root privileges within the container, significantly increasing the blast radius of any compromise. Fix: Create a dedicated non-root user in the Dockerfile and switch to it before running the application. For example: 'RUN addgroup -S mermaid && adduser -S mermaid -G mermaid' followed by 'USER mermaid'. - High · XSS Risk via Diagram Text Rendering —
packages/mermaid/src (diagram rendering pipeline). Mermaid renders user-supplied text input into SVG diagrams in the browser DOM. If user-controlled input is not strictly sanitized before being rendered into SVG/HTML, it may allow cross-site scripting (XSS) attacks. The project's nature (text-to-diagram) makes it a high-value XSS target, especially when used in contexts that render untrusted user-provided diagram definitions. Fix: Ensure all diagram input is sanitized using a well-maintained HTML sanitization library (e.g., DOMPurify) before injection into the DOM. Review all innerHTML assignments and SVG property injections. Enforce a strict Content Security Policy (CSP) in consuming applications. - High · Sensitive Environment Variables via .env File —
docker-compose.yml, .env. The docker-compose.yml references an 'env_file: .env', which loads environment variables from a local .env file. If this file contains secrets (API keys, tokens, credentials) and is accidentally committed to the repository or exposed, it could lead to credential leakage. There is no .gitignore entry visible to confirm the .env file is excluded. Fix: Ensure .env is listed in .gitignore and never committed to version control. Use a secrets management solution (e.g., HashiCorp Vault, Docker Secrets, environment-specific CI/CD secret injection) instead of flat .env files for sensitive values. Provide a .env.example file with placeholder values. - High · Host Network Mode for Cypress Container —
docker-compose.yml (cypress service). The cypress service in docker-compose.yml uses 'network_mode: host', which removes all network isolation between the container and the host. This means the Cypress container can access all services on the host network, increasing the attack surface if the Cypress container or its dependencies are compromised. Fix: Avoid using 'network_mode: host' unless absolutely necessary. Use Docker bridge networks instead and explicitly define only the required port mappings and inter-service communication. - High · Outdated/Pinned Package Manager with Potentially Insecure Hash —
package.json (packageManager field). The package.json specifies 'pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017'. The SHA-512 hash appears truncated (valid SHA-512 is 128 hex characters; this hash is shorter), which could indicate a corrupted or invalid integrity check, potentially allowing a tampered pnpm version to be used without detection. Fix: Verify the correct and complete SHA-512 hash for the specified pnpm version using the official pnpm release checksums. Regenerate the packageManager field using 'corepack use pnpm@10.30.3' to ensure integrity. - Medium · Exposed Development Ports Without Authentication —
Dockerfile, docker-compose.yml. The Dockerfile exposes ports 9000 and 3333, and docker-compose.yml maps port 3333 to the host. These appear to be development server ports with no mention of authentication or TLS. If exposed on a network-accessible interface, unauthorized parties could access the development server and potentially the source code or application internals. Fix: Bind development server ports to localhost (127.0.0.1) only in docker-compose.yml (e.g., '127.0.0.1:3333:3333'). Ensure development servers are never exposed on public-facing interfaces. Add authentication to any
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.