KEMBAR78
textlint/textlint | DeepWiki
Menu

Overview

Relevant source files

Purpose and Scope

textlint is a pluggable natural language linting tool for prose, similar to ESLint but designed for checking written text rather than code. This document provides a high-level overview of textlint's architecture, core concepts, and position in the JavaScript ecosystem.

For detailed information on specific subsystems:

  • For architectural details and data flow, see Architecture
  • For monorepo organization and package management, see Monorepo Structure
  • For catalog of packages and their responsibilities, see Key Packages
  • For definitions of core concepts (AST, TxtNode, rules, plugins, etc.), see Terminology

What is textlint?

textlint is a command-line tool and Node.js module that checks natural language text for style, grammar, and consistency issues. Unlike spell checkers, textlint operates on an Abstract Syntax Tree (AST) representation of documents, enabling sophisticated structural analysis and automatic fixes.

Key characteristics:

  • Zero bundled rules: Users choose and install only the rules they need
  • Pluggable architecture: Support for Markdown, plain text, HTML, and custom formats via plugins
  • Universal JavaScript: Core logic (@textlint/kernel) runs in both Node.js and browser environments
  • Fixable rules: Many rules can automatically correct issues via --fix flag
  • ESLint-inspired: Follows ESLint's design patterns for familiarity to JavaScript developers

Sources: README.md1-53 packages/textlint/package.json2-14

System Architecture

textlint processes text through a four-stage pipeline:

Sources: Diagram 2 from provided architecture overview, packages/textlint/package.json50-64

Core Processing Flow

Sources: packages/textlint/src/index.ts structure, packages/@textlint/kernel/src/index.ts

Position in the JavaScript Ecosystem

textlint integrates with the JavaScript/TypeScript development ecosystem through multiple touchpoints:

Integration PointPackage/ToolPurpose
Package Managernpm, pnpmRule/plugin distribution
Build ToolsBabel, TypeScriptRule development transpilation
TestingMocha, vitestRule testing framework
MonorepoLernaVersion management and publishing
EditorsVS Code, Vim, AtomReal-time linting integration
CI/CDGitHub ActionsAutomated quality checks
AI AssistantsMCP (Model Context Protocol)Integration with Copilot, Cursor

Sources: package.json44-60 README.md442-500 packages/textlint/package.json51

High-Level Package Organization

The textlint monorepo contains 30+ packages organized by function:

Sources: README.md510-561 Diagram 1 from architecture overview

Key Design Decisions

1. Zero Default Rules

Unlike many linters, textlint ships with no bundled rules. Users explicitly install rules via npm (e.g., npm install textlint-rule-no-todo). This keeps the core lightweight and allows users to build custom rule sets.

Sources: README.md30-33 README.md72-104

2. AST-Based Processing

textlint converts text to an Abstract Syntax Tree (TxtNode structure) rather than processing raw strings. This enables:

  • Structural awareness (e.g., distinguishing code blocks from prose)
  • Position-accurate error reporting with line/column numbers
  • Context-aware rules (e.g., different rules for headings vs. paragraphs)

Sources: docs/txtnode.md1-66 packages/@textlint/ast-node-types/src/index.ts

3. Universal JavaScript Core

The @textlint/kernel package is written as universal JavaScript, allowing it to run in:

  • Node.js (CLI and server-side tools)
  • Browsers (web-based editors and demos)
  • Non-Node environments (Deno, etc.)

The CLI wrapper (textlint package) handles Node-specific concerns like file I/O and configuration loading.

Sources: packages/@textlint/kernel/package.json1-4 README.md378-405

4. Plugin Architecture

File format support is delegated to plugins that provide Processor classes. Each processor defines:

  • availableExtensions(): Supported file extensions (e.g., [".md", ".markdown"])
  • processor(ext).preProcess(): Parse text to AST
  • processor(ext).postProcess(): Transform results back to file context

Built-in plugins support Markdown and plain text; community plugins add HTML, AsciiDoc, ReStructuredText, etc.

Sources: docs/plugin.md9-63 packages/@textlint/textlint-plugin-markdown/src/index.ts

5. Separation of Linting and Fixing

textlint maintains separate code paths for:

  • Linting: lintText()/lintFiles()TextlintResult[] with error messages
  • Fixing: fixText()/fixFiles()TextlintFixResult[] with corrected text

This separation allows rules to provide optional fix functions without complicating the linting logic.

Sources: docs/use-as-modules.md29-46 packages/@textlint/kernel/src/index.ts

Entry Points

Command-Line Interface

The textlint package provides the main CLI entry point at packages/textlint/bin/textlint.js Users typically invoke it via:

Key CLI flags:

  • --rule <rule-name>: Enable a rule without .textlintrc
  • --fix: Apply automatic fixes
  • --format <formatter>: Choose output format (stylish, json, etc.)
  • --config <path>: Specify configuration file
  • --mcp: Start Model Context Protocol server for AI integration

Sources: README.md105-162 packages/textlint/bin/textlint.js

Programmatic API (v15+)

For Node.js integration, the textlint package exports modern high-level APIs:

Sources: docs/use-as-modules.md1-65 packages/textlint/src/index.ts

Low-Level Kernel API

The @textlint/kernel package provides direct access to the linting engine for browser environments or custom integrations:

Sources: README.md378-405 packages/@textlint/kernel/src/textlint-kernel-interface.ts

Development Workflow Support

textlint provides comprehensive tooling for rule and plugin developers:

Sources: packages/textlint-scripts/package.json1-5 packages/textlint-tester/package.json1-5 docs/rule.md373-416

Configuration Model

textlint uses a flexible configuration file (.textlintrc, .textlintrc.json, .textlintrc.js, etc.) that specifies:

SectionPurposeExample
rulesEnable/configure linting rules{ "no-todo": true }
filtersEnable error filtering rules{ "comments": true }
pluginsAdd file format support{ "html": { "extensions": [".htm"] } }

Configuration loading is handled by @textlint/config-loader using rc-config-loader for flexible file format support (JSON, YAML, JS).

Sources: docs/configuring.md1-298 packages/@textlint/config-loader/src/index.ts

Extensibility Points

textlint provides four primary extension mechanisms:

Extension TypePackage PrefixPurposeExample
Rulestextlint-rule-Check text for issuestextlint-rule-no-todo
Rule Presetstextlint-rule-preset-Bundle multiple rulestextlint-rule-preset-ja-spacing
Pluginstextlint-plugin-Add file format supporttextlint-plugin-html
Filter Rulestextlint-filter-rule-Suppress specific errorstextlint-filter-rule-comments

All extensions follow npm naming conventions and can be scoped (e.g., @scope/textlint-rule-name).

Sources: README.md409-421 docs/configuring.md24-298

Version and Compatibility

  • Current version: 15.2.2 (as of latest package.json)
  • Node.js requirement: 20.0.0+ (all packages)
  • Breaking change policy: Follows Semantic Versioning with textlint-specific interpretations
    • Patch: Bug fixes, documentation updates
    • Minor: New options, new public APIs (may break TypeScript types)
    • Major: Removed APIs, more restrictive default behavior

Sources: packages/textlint/package.json3-95 README.md563-584

Monorepo Structure

The repository uses Lerna + pnpm workspaces for managing 30+ interdependent packages:

  • Root package.json: Defines workspace scripts and shared devDependencies
  • lerna.json: Version management and publishing configuration
  • pnpm-workspace.yaml: Workspace package locations
  • Package references: TypeScript project references for type checking across packages

Key scripts:

  • pnpm run build: Build all packages
  • pnpm run test: Run all tests
  • pnpm run ci:release: Publish all changed packages

Sources: package.json1-61 lerna.json pnpm-lock.yaml1-10