Skip to content
CAI
Software that uses CAICheck a score

showdownjs/showdown

48.3

Weak · 1 October 2026

15.7k

lines of production code

JavaScript

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Markdown conversion library that provides bidirectional translation between Markdown and HTML formats. It features a modular, event-driven architecture with a command-line interface for processing text files and streams. The toolset includes robust security hardening against XSS and ReDoS attacks, alongside comprehensive testing infrastructure for performance and cross-browser compatibility.

How it got here

2008–2015 — v3.0.0-rc1 architecture and CLI modernization

9 changes.

This period centered on the v3.0.0-rc1 release, which involved refactoring the core engine into modular components with a new event system and removing legacy artifacts. It also introduced a new command-line interface for Markdown conversion and modernized the build toolchain to require Node.js 20+.

2016–2017 — Performance optimization and security hardening

8 changes.

This period focused on refactoring the inline parser to eliminate quadratic scanning and improve CommonMark compliance, while introducing a safe mode to mitigate XSS and ReDoS vulnerabilities. The work was supported by extensive new testing infrastructure, including performance benchmarks and comprehensive functional and unit tests for both Markdown-to-HTML and HTML-to-Markdown conversions.

2018–2026 — HTML-to-Markdown conversion and tooling migration

9 changes.

This period focused on implementing a comprehensive HTML-to-Markdown conversion feature, supported by extensive functional testing for GFM elements like task lists, footnotes, and emoji. Concurrently, the project modernized its build infrastructure by migrating from Grunt/Karma to esbuild/Vitest and refactored helper modules to improve maintainability and fix security issues in HTML comment parsing.

Features

Introduce ShowdownJS command-line interface

Adds a new CLI tool (\src/cli/cli.js\) built on Commander, exposing \makehtml\ and \makemarkdown\ subcommands for converting between Markdown and HTML. The interface supports reading from stdin or files (including glob patterns), writing to stdout or specific output directories, and includes options for input/output encoding, appending to files, loading extensions, and selecting parser flavors (e.g., GFM). It also features quiet, mute, and verbose modes, along with configurable colored output for better terminal usability.

src/cli · high confidence

New HTML-to-Markdown conversion capability

The \src/subParsers/makemarkdown\ directory now contains a complete set of subparsers that convert HTML back into Markdown. This new feature supports a wide range of elements including blockquotes, headers, lists, links, images, code blocks, tables, and inline formatting like emphasis and strikethrough. It also handles specific GitHub Flavored Markdown (GFM) features such as task lists, footnotes, and emoji/ellipsis reversal, while respecting existing converter options to ensure symmetric behavior with the HTML-to-Markdown direction.

src/subParsers/makemarkdown · high confidence

Removals

Removal of compressed Showdown.js build artifact

The minified version of the Showdown library (compressed/showdown.js) has been deleted from the repository. This change removes the pre-built, uglified output file, meaning users relying on this specific artifact will no longer have access to it in this location.

compressed · high confidence

Removal of legacy example files

The \showdown-gui.html\, \showdown-gui.js\, and \showdown.js\ files in the \example\ directory have been deleted. This removes the previous client-side Markdown preview GUI and its associated JavaScript implementation from the project's examples.

example · high confidence

Removed legacy Perl Markdown reference implementation

The \perlMarkdown\ directory, which contained John Gruber's original Perl Markdown scripts (versions 1.0.2b2 and 1.0.2b7) and associated documentation, has been deleted. This removes the legacy Perl source files and license text from the project.

perlMarkdown · high confidence

Architecture

Refactored converter into modular components with a new event system

The core conversion engine has been restructured from a single monolithic file into separate modules: \converter.js\ (the instance engine), \event.js\ (the listener event system), \loader.js\ (module exports), and \options.js\ (option declarations). This change introduces a new event dispatcher that allows extensions to hook into the conversion pipeline via named events rather than legacy language/output hooks, and standardizes how options are managed and exposed.

src · high confidence

Behavioural changes

266 commits (112 fixes) modifying dist

A change to existing behaviour in dist — 266 commits (112 fixs), 6 files.

bin, dist · medium confidence · unverified

Build and test tooling migrated from Grunt/Karma to esbuild/Vitest

The project's build and testing infrastructure has been replaced: the Grunt toolchain and JSHint/legacy ESLint are removed in favor of esbuild for bundling and ESLint 9 flat config for linting, while the Karma+Mocha test runner is replaced by Vitest (using jsdom for Node tests and Playwright for browser tests). This migration introduces new Node.js scripts (build.mjs, concat.mjs, release.mjs, etc.) that handle source concatenation, UMD/ESM/CLI artifact generation, and an interactive release workflow with a dry-run mode, ensuring the same output artifacts and test coverage with a modern, faster toolchain.

scripts · high confidence

Configurable drawer navigation title

The slide-out navigation drawer now displays a distinct title from the main header. Users can set a specific label via the \config.extra.drawer\_title\ configuration option, which will appear in the drawer; if this option is not provided, it falls back to the site name (\config.site\_name\).

overrides · high confidence

Restructured helper modules and hardened HTML comment parsing

The \src/helpers\ directory has been split from a single monolithic file into themed modules (e.g., \commonmark.js\, \escapes.js\, \gfmAutolinks.js\), improving maintainability without changing the public API. This refactor includes a security fix for HTML comment parsing: comments are now correctly terminated by \--!\>\ in addition to \--\>\, preventing content that should be commented out from leaking through as live HTML. The change also introduces a shared character-reference decoder and unified GFM anchor machinery to ensure consistent behavior across CommonMark and legacy parsing paths.

src/helpers · high confidence

Unified inline parser and hardened security for makehtml

The \src/subParsers/makehtml\ directory has been refactored to use a single-pass inline scanner that replaces the previous multi-pass approach, introducing new subparsers for constructs like autolinks, backslash escapes, code spans, and emphasis. This change improves performance by removing quadratic scanning and enhances CommonMark compliance. Additionally, a new \safeMode\ option has been added to harden the converter against XSS and ReDoS attacks, including the introduction of a \disallowedHtmlTags\ filter that neutralizes dangerous raw HTML tags and strips inline event handlers.

src/subParsers/makehtml · high confidence

Test coverage

Added BrowserStack real-device smoke tests; Added functional tests for GFM footnote conversion; Added functional tests for emoji and ellipsis handling; Added functional tests for makeMarkdown reverse conversion; Added functional tests for makemarkdown fallback cases; Added performance test suite and Vitest configuration; Added performance testing infrastructure and benchmarks; Added regression tests for Markdown parsing issues; Added test coverage for tasklist checkbox edge cases; Added test fixtures for CLI markdown conversion; Expanded functional test coverage for HTML-to-Markdown conversion; Expanded functional test coverage for makeHtml; Expanded unit test coverage for CLI, event system, and security regressions.

Dependencies

Upgrade to Node 20+ and modernize build/test toolchain

Showdown now requires Node.js 20 or later and replaces the legacy Grunt build system with esbuild for faster bundling. The test runner has shifted from Karma/Mocha to Vitest with Playwright for browser testing, and linting is now handled by ESLint 10. Runtime dependencies have been updated to commander ^14.0.0 and happy-dom ^20.10.6, while dev dependencies include jsdom ^27.0.0 and various modernized tooling packages. A new docs/requirements.txt pins mkdocs-material \>=9.4 for documentation builds.

(dependencies) · high confidence

Housekeeping

Repository initialization with v3.0.0-rc1 changelog and configuration scaffolding

The repository has been initialized with the source and configuration for version 3.0.0-rc1. This entry documents the addition of the project scaffolding, including the \.editorconfig\ for code style, \.gitattributes\ to enforce LF line endings, and \.gitignore\ for build artifacts. It also includes the \CHANGELOG.md\ detailing the v3.0.0-rc1 release, which introduces a new event system, CommonMark compliance improvements, and several breaking changes (such as the removal of \openLinksInNewWindow\ and \literalMidWordAsterisks\ options). The \README.md\ and \SECURITY.md\ are added to document usage and security policies, while \CONTRIBUTING.md\ outlines contribution guidelines.

(repo-wide) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 53 → 48 (-5.2)
  • Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 41 → 36 (-4.6)
  • Architecture 99 → 99 (+0.4)
  • Maturity 59 → 58 (-0.7)
  • Readiness 56 → 42 (-13.8)
  • Security 90 → 83 (-7.0)
  • Performance 100 (new)

Resolved (16)

  • Converter (cyclomatic 60) (src/converter.js)
  • Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (no pnpm-resolved versions to grade)
  • Documentation: no architecture or design documentation (docs/api-reference.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no installation or build instructions (docs/cli.md)
  • Hotspot: src/helpers/misc.js (src/helpers/misc.js)
  • Hotspot: src/helpers/text.js (src/helpers/text.js)
  • Hotspot: src/helpers/url.js (src/helpers/url.js)
  • Hotspot: src/subParsers/makehtml/rawHtml.js (src/subParsers/makehtml/rawHtml.js)
  • Off-boarding risk: anonymized user #1
  • _populateAttributes (cyclomatic 18) (src/helpers/misc.js)
  • cmScanDestination (cognitive 33) (src/helpers/commonmark.js)
  • cmScanDestination (cyclomatic 22) (src/helpers/commonmark.js)
  • dispatchCapture (cyclomatic 16) (src/event.js)
  • writeAnchorTag (cognitive 28) (src/helpers/gfmAutolinks.js)
  • writeAnchorTag (cyclomatic 21) (src/helpers/gfmAutolinks.js)

New (72)

  • Dependency hygiene PARTLY measured — Python dependencies read, no exact pin to grade for currency
  • Documentation: no architecture or design documentation (docs/quickstart.md)
  • Documentation: no contributor guidance (README.md)
  • Documentation: no project overview (README.md)
  • FunctionTooLong: blockquote.showdown.subParser("makehtml.blockquote") (src/subParsers/makehtml/blockquote.js)
  • FunctionTooLong: footnotes.showdown.subParser("makehtml.footnotes") (src/subParsers/makehtml/footnotes.js)
  • FunctionTooLong: node.showdown.subParser("makeMarkdown.node") (src/subParsers/makemarkdown/node.js)
  • FunctionTooLong: table.showdown.subParser("makeMarkdown.table") (src/subParsers/makemarkdown/table.js)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • Hotspot: src/converter.js (src/converter.js)
  • Hotspot: src/subParsers/makehtml/heading.js (src/subParsers/makehtml/heading.js)
  • Hotspot: src/subParsers/makehtml/htmlBlock.js (src/subParsers/makehtml/htmlBlock.js)
  • Hotspot: src/subParsers/makehtml/link.js (src/subParsers/makehtml/link.js)
  • Hotspot: src/subParsers/makehtml/spanGamut.js (src/subParsers/makehtml/spanGamut.js)
  • Hotspot: src/subParsers/makemarkdown/footnotes.js (src/subParsers/makemarkdown/footnotes.js)
  • Hotspot: src/subParsers/makemarkdown/image.js (src/subParsers/makemarkdown/image.js)
  • Hotspot: src/subParsers/makemarkdown/input.js (src/subParsers/makemarkdown/input.js)
  • …and 52 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

showdownjs/showdown was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit d1a8d16344b855ea2f37677ee8a9e0cc2c597ea4 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.