mdast-util-to-string

Get the plain-text content of any mdast node in a single function call.

Library
npm
v4.0.0
47stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
28/100Needs Attention
Development Activity0
Maintenance20
Community20
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
82/100Excellent
Architecture85
Code Quality92
Innovation82
Learning Curve68

mdast-util-to-string is a tiny utility from the unified/syntax-tree ecosystem that extracts the textual content of an mdast (Markdown Abstract Syntax Tree) node. Given a heading, paragraph, or any other node — or an array of nodes — it walks the node’s plain-text fields and children, unwrapping emphasis, strong, links, and other inline formatting into a single flat string.

It intentionally does one job well: it does not serialize back to Markdown (that’s mdast-util-to-markdown’s job) and has no notion of rendering — only of collapsing a tree into text. It’s the mdast counterpart to hast-util-to-string/hast-util-to-text for HTML ASTs, and is a common building block behind slug generation, search indexing, table-of-contents extraction, and word counts in remark-based tooling.

What You Get

  • A single toString(value, options) export with no default export — small, tree-shakeable surface area
  • Recursive serialization that handles single nodes, node lists, and deeply nested children uniformly
  • Configurable includeImageAlt and includeHtml options to control whether image alt text and raw HTML nodes contribute to the output
  • Full TypeScript types generated from JSDoc, with the Options type exported for consumers
  • Zero runtime dependencies beyond the type-only @types/mdast package
  • Battle-tested inside the wider unified/remark/rehype toolchain, so behavior matches what remark-based tools already expect

Common Use Cases

  • Generating heading slugs or anchor text from a heading node’s rendered content
  • Building a table of contents by extracting plain text from heading nodes across a document
  • Feeding markdown content into full-text search indexes that expect plain strings, not markup
  • Computing word counts or reading-time estimates from parsed Markdown/MDX content
  • Stripping formatting from a node for use in meta descriptions, previews, or notifications

Under The Hood

Architecture The entire implementation lives in one small module (lib/index.js) built around three tiny functions: one (serialize a single value), all (join serialized results across a list), and node (a type guard checking whether a value looks like an mdast node). toString normalizes options and delegates to one, which prefers a node’s own value field, then an alt field (for images, when enabled), then recurses into children via all, and falls through to an empty string otherwise. There is no class hierarchy, no internal state, and no I/O — just a pure recursive walk — which keeps the module trivial to reason about and reuse as a building block inside larger unified/remark-util packages, mirroring the same one/all recursion shape used by its hast-util sibling packages.

Tech Stack The package is plain ESM JavaScript ("type": "module"), typed entirely through JSDoc comments and compiled to declaration files via tsc --build with strict mode and 100% type-coverage enforced at build time. Its only runtime dependency is the type-only @types/mdast package. Linting and formatting run through xo (wrapping ESLint) and prettier, with remark-preset-wooorm used to lint the README itself, and coverage is measured with c8. CI runs on GitHub Actions across the current and LTS Node.js releases.

Code Quality test.js uses Node’s built-in node:test and node:assert/strict — no external test framework — and asserts both the exported public API surface and behavior across every branch: missing values, null, valueless nodes, value-over-alt-over-children precedence, includeImageAlt/includeHtml toggles, and list serialization. The test-coverage script enforces c8 --100, meaning the suite is required to hit 100% statement/branch coverage on every release. Combined with type-coverage’s 100% requirement and xo’s strict lint rules, the project holds itself to an unusually rigorous bar for a package this small.

API Design The public surface is a single named export, toString, taking one required argument and one optional options object with two well-named boolean flags — there is no setup, no configuration object to construct, and no boilerplate beyond installing the package and importing the function. Naming and behavior are consistent with sibling utilities across the syntax-tree organization (hast-util-to-string, hast-util-to-text), so developers already familiar with one unified/rehype/remark utility can predict this one’s behavior without reading the docs, though the README’s API section is thorough enough that reading isn’t strictly necessary either.

Used by 7 apps in this directory

Rust
52%
Apache 2.0

cocoindex

Data Engineering · AI Development

11,496

An incremental data indexing engine that keeps AI agent context perpetually fresh by reprocessing only what changed.

View details
86
Repo Health
85
Technical
64
Dependency
Built with
Rust52%
Python48%
Updated 2 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,634

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
97%
Other

Rocket.Chat

Team Chat

46,089

The secure, self-hosted team communications platform for organizations that cannot compromise on data sovereignty.

View details
96
Repo Health
79
Technical
66
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
71%
Apache 2.0

Supabase

Developer Tools · Databases · Search

108,912

The open-source Postgres development platform that replaces Firebase with authentication, real-time APIs, edge functions, storage, and vector embeddings — all built on PostgreSQL.

View details
90
Repo Health
91
Technical
62
Dependency
Built with
TypeScript71%
MDX26%
Updated today
TypeScript
92%
Apache 2.0

superset

AI Code Assistants · AI Development

13,825

Orchestrate an army of AI coding agents—Claude Code, Codex, Gemini CLI, and more—running simultaneously in isolated git worktrees from a single Electron desktop app.

View details
85
Repo Health
80
Technical
67
Dependency
Built with
TypeScript92%
Updated today
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

8,910

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript99%
Updated today
Python
57%
Apache 2.0

Zulip

Team Chat

25,855

Topic-based team chat that brings the structure of email threads to real-time messaging, so distributed teams never lose context across hundreds of concurrent conversations.

View details
96
Repo Health
86
Technical
61
Dependency
Built with
Python57%
TypeScript19%
JavaScript10%
Updated yesterday

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search