CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-remark

Unified markdown processor powered by plugins with parsing, transformation, and stringification capabilities

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Remark

Remark is a unified markdown processor powered by plugins that provides parsing, transformation, and stringification capabilities for markdown documents. It exports a single pre-configured unified processor that combines remark-parse and remark-stringify into a ready-to-use markdown processing pipeline.

Package Information

  • Package Name: remark
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install remark

Core Imports

import { remark } from "remark";

For CommonJS:

const { remark } = require("remark");

Basic Usage

import { remark } from "remark";

// Process markdown through complete pipeline
const file = await remark.process("# Hello World\n\nThis is **markdown**.");
console.log(String(file)); // "# Hello World\n\nThis is **markdown**.\n"

// Parse markdown to AST
const tree = remark.parse("# Hello World");
console.log(tree.type); // "root"

// Add plugins for extended functionality
const processor = remark
  .use(remarkGfm) // Add GitHub Flavored Markdown support
  .use(remarkToc, { heading: "Contents" }); // Add table of contents
  
const result = await processor.process(markdownContent);

Architecture

Remark is built on the unified ecosystem and provides:

  • Pre-configured Processor: A frozen unified processor combining remark-parse and remark-stringify
  • Plugin System: Extensible architecture for adding markdown processing capabilities through unified
  • MDAST Integration: Works with MDAST (Markdown Abstract Syntax Tree) format from @types/mdast
  • VFile Support: Enhanced file handling with metadata and error reporting through vfile
  • Frozen Interface: Immutable processor pattern preventing further configuration after creation

Capabilities

Main Export

The remark package exports a single pre-configured unified processor.

/**
 * Pre-configured unified processor with remark-parse and remark-stringify
 * This is a frozen processor instance, not a function
 */
const remark: Processor<Root, undefined, undefined, Root, string>;

Processing Methods

All processing methods are inherited from the unified processor interface:

Process Pipeline

Process markdown through the complete pipeline (parse → transform → stringify).

/**
 * Process markdown input through complete pipeline
 * @param file - Markdown string or VFile to process
 * @returns Promise resolving to processed VFile
 */
remark.process(file: string | VFile): Promise<VFile>;

/**
 * Synchronous version of process()
 * @param file - Markdown string or VFile to process  
 * @returns Processed VFile
 */
remark.processSync(file: string | VFile): VFile;

Parse Operations

Parse markdown to MDAST abstract syntax tree.

/**
 * Parse markdown to MDAST AST
 * @param file - Markdown string or VFile to parse
 * @returns MDAST Root node
 */
remark.parse(file: string | VFile): Root;

Stringify Operations

Convert MDAST abstract syntax tree to markdown string.

/**
 * Convert MDAST AST to markdown string
 * @param tree - MDAST Root node to stringify
 * @param file - Optional VFile for context
 * @returns Markdown string
 */
remark.stringify(tree: Root, file?: VFile): string;

Transform Operations

Run transformation plugins on MDAST abstract syntax tree.

/**
 * Run transformation plugins on AST
 * @param tree - MDAST Root node to transform
 * @param file - Optional VFile for context
 * @returns Promise resolving to transformed Root node
 */
remark.run(tree: Root, file?: VFile): Promise<Root>;

/**
 * Synchronous version of run()
 * @param tree - MDAST Root node to transform
 * @param file - Optional VFile for context
 * @returns Transformed Root node
 */
remark.runSync(tree: Root, file?: VFile): Root;

Plugin Management

Plugin Registration

Add plugins or presets to extend processor capabilities.

/**
 * Add plugin to processor
 * @param plugin - Plugin function to add
 * @param options - Optional plugin configuration
 * @returns New processor instance with plugin added
 */
remark.use(plugin: Plugin, options?: any): Processor<Root, undefined, undefined, Root, string>;

/**
 * Add preset to processor
 * @param preset - Plugin preset to add
 * @returns New processor instance with preset added
 */
remark.use(preset: Preset): Processor<Root, undefined, undefined, Root, string>;

/**
 * Add list of plugins to processor
 * @param list - Array of plugins/presets to add
 * @returns New processor instance with plugins added
 */
remark.use(list: PluggableList): Processor<Root, undefined, undefined, Root, string>;

Configuration Management

Data Storage

Get or set processor configuration data and settings.

/**
 * Get configuration value
 * @param key - Configuration key to retrieve
 * @returns Configuration value
 */
remark.data(key: string): any;

/**
 * Set configuration value
 * @param key - Configuration key to set
 * @param value - Configuration value to set
 * @returns Processor instance for chaining
 */
remark.data(key: string, value: any): Processor<Root, undefined, undefined, Root, string>;

/**
 * Set multiple configuration values
 * @param dataset - Object containing configuration key-value pairs
 * @returns Processor instance for chaining
 */
remark.data(dataset: Record<string, any>): Processor<Root, undefined, undefined, Root, string>;

Extension Configuration

Configure remark-parse and remark-stringify extensions via data.

/**
 * Configure micromark extensions for parsing
 * Used by remark-parse to extend markdown syntax
 */
remark.data("micromarkExtensions", extensions: MicromarkExtension[]): Processor;

/**
 * Configure fromMarkdown extensions for parsing  
 * Used by remark-parse to handle extended syntax nodes
 */
remark.data("fromMarkdownExtensions", extensions: FromMarkdownExtension[]): Processor;

/**
 * Configure toMarkdown extensions for stringification
 * Used by remark-stringify to output extended syntax
 */
remark.data("toMarkdownExtensions", extensions: ToMarkdownExtension[]): Processor;

/**
 * Configure stringify settings
 * Used by remark-stringify for output formatting
 */
remark.data("settings", settings: StringifySettings): Processor;

Processor Properties

/**
 * Create frozen processor instance (prevents further .use() calls)
 * @returns Frozen processor instance
 */
remark.freeze(): Processor<Root, undefined, undefined, Root, string>;

/**
 * Whether processor is frozen (always true for remark export)
 */
readonly remark.frozen: boolean;

Types

Core Types from Dependencies

Remark works with types from its dependencies:

/**
 * MDAST root node representing markdown document
 * From @types/mdast package
 */
interface Root {
  type: "root";
  children: Array<RootContent>;
  position?: Position;
}

/**
 * Virtual file with path, content, and metadata  
 * From vfile package
 */
interface VFile {
  readonly path?: string;
  value: string;
  readonly data: Record<string, unknown>;
  readonly messages: Array<VFileMessage>;
  readonly history: Array<string>;
  readonly cwd: string;
}

/**
 * Unified processor interface
 * From unified package
 */
interface Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult> {
  parse(file: string | VFile): ParseTree;
  stringify(tree: CompileTree, file?: VFile): CompileResult;
  run(tree: HeadTree, file?: VFile): Promise<TailTree>;
  runSync(tree: HeadTree, file?: VFile): TailTree;
  process(file: string | VFile): Promise<VFile>;
  processSync(file: string | VFile): VFile;
  use(plugin: Plugin, options?: any): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
  data(key: string): any;
  data(key: string, value: any): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
  freeze(): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
  readonly frozen: boolean;
}

/**
 * Plugin function type
 * From unified package
 */
type Plugin = (this: Processor, options?: any) => void | Transformer;

/**
 * Transformation function type
 * From unified package
 */
type Transformer = (tree: Node, file?: VFile) => void | Node | Promise<void | Node>;

/**
 * Plugin or plugin tuple type
 * From unified package
 */
type Pluggable = Plugin | [Plugin, any] | Preset;

/**
 * List of pluggables
 * From unified package
 */
type PluggableList = Array<Pluggable>;

/**
 * Plugin preset configuration
 * From unified package
 */
interface Preset {
  settings?: Record<string, any>;
  plugins?: PluggableList;
}

Extension Types

/**
 * Micromark extension for parsing
 * From micromark package
 */
interface MicromarkExtension {
  document?: Record<string, any>;
  contentInitial?: Record<string, any>;
  flowInitial?: Record<string, any>;
  flow?: Record<string, any>;
  string?: Record<string, any>;
  text?: Record<string, any>;
}

/**
 * FromMarkdown extension for AST construction
 * From mdast-util-from-markdown package
 */
interface FromMarkdownExtension {
  canContainEols?: Array<string>;
  enter?: Record<string, any>;
  exit?: Record<string, any>;
}

/**
 * ToMarkdown extension for stringification
 * From mdast-util-to-markdown package
 */
interface ToMarkdownExtension {
  extensions?: Array<any>;
}

Configuration Options

Stringify Settings

Configure markdown output formatting via the settings data key:

remark.data("settings", {
  bullet: "*",              // Bullet list marker ("-", "*", "+")  
  bulletOrdered: ".",       // Ordered list marker (".", ")")
  closeAtx: false,          // Close ATX headings with #
  emphasis: "*",            // Emphasis marker ("*", "_")
  fence: "`",               // Code fence marker ("`", "~")
  fences: true,             // Use fences for code blocks
  incrementListMarker: true, // Increment ordered list markers
  listItemIndent: "one",    // List indentation ("tab", "one", "mixed")
  quote: '"',               // Quote marker for titles ('"', "'")
  rule: "*",                // Horizontal rule marker ("-", "*", "_")
  ruleRepetition: 3,        // HR marker repetition count
  ruleSpaces: false,        // Spaces around HR markers
  setext: false,            // Use setext headings (underlined)
  strong: "*",              // Strong emphasis marker ("*", "_")
  tightDefinitions: false   // Tight definition formatting
});

Extension Configuration

// Add micromark extensions for parsing
remark.data("micromarkExtensions", [gfmExtension]);

// Add fromMarkdown extensions for AST handling
remark.data("fromMarkdownExtensions", [gfmFromMarkdown]);

// Add toMarkdown extensions for stringification
remark.data("toMarkdownExtensions", [gfmToMarkdown]);

Usage Examples

Basic Processing

import { remark } from "remark";

// Simple processing
const file = await remark.process("# Hello\n\nWorld!");
console.log(String(file)); // "# Hello\n\nWorld!\n"

With Plugins

import { remark } from "remark";
import remarkGfm from "remark-gfm";
import remarkToc from "remark-toc";

const processor = remark
  .use(remarkGfm)
  .use(remarkToc, { heading: "contents", tight: true });

const result = await processor.process(markdownWithTables);

Custom Configuration

import { remark } from "remark";

const processor = remark
  .data("settings", {
    bulletOrdered: ")",
    incrementListMarker: false,
    setext: true,
    emphasis: "_"
  });

const formatted = await processor.process(inputMarkdown);

AST Manipulation

import { remark } from "remark";
import type { Root } from "mdast";

// Parse to AST
const tree = remark.parse("# Hello World") as Root;

// Modify AST
tree.children.push({
  type: "paragraph",
  children: [{ type: "text", value: "Added content" }]
});

// Convert back to markdown
const markdown = remark.stringify(tree);

Extension Usage

import { remark } from "remark";
import { gfm } from "micromark-extension-gfm";
import { gfmFromMarkdown, gfmToMarkdown } from "mdast-util-gfm";

const processor = remark
  .data("micromarkExtensions", [gfm()])
  .data("fromMarkdownExtensions", [gfmFromMarkdown()])
  .data("toMarkdownExtensions", [gfmToMarkdown()]);

const result = await processor.process("| Column 1 | Column 2 |\n|----------|----------|\n| Cell 1   | Cell 2   |");

docs

index.md

tile.json