Slack Message Parser
slack-message-parser is a JavaScript/TypeScript library designed to parse Slack's rich message formatting syntax into a structured Abstract Syntax Tree (AST). This allows developers to programmatically inspect, transform, or render Slack messages outside of the Slack client itself. The current stable version is 3.0.2. The library maintains a steady release cadence, primarily focusing on bug fixes, improvements to parsing accuracy, and adapting to changes in Node.js environments, with major versions introducing breaking changes like the shift to ESM and higher Node.js version requirements. A key differentiator of slack-message-parser is its output: instead of directly rendering to a format like HTML, it provides a hierarchical AST, enabling highly customizable processing, such as converting to various markup languages, performing content analysis, or implementing custom rendering logic. It ships with comprehensive TypeScript types, ensuring robust and type-safe development.
Common errors
-
SyntaxError: Cannot use import statement outside a module
cause Attempting to use ES Module `import` syntax in a CommonJS (CJS) project context, particularly after v3.0.0 shifted the library to ESM.fixEnsure your project is configured as an ES Module (e.g., by adding `"type": "module"` to `package.json` or using `.mjs` file extensions), or use dynamic `import()` if you must remain in CJS. -
TypeError: slackMessageParser is not a function
cause Incorrectly attempting to `require()` the default export of `slack-message-parser` in a Node.js environment where the package is treated as an ESM, especially in v3.0.0 and above.fixUse the ESM `import` syntax: `import slackMessageParser from 'slack-message-parser';`. If you must use `require()` in a CJS context, try `const { default: slackMessageParser } = require('slack-message-parser');` or ensure Node.js correctly interops. -
Property 'children' does not exist on type 'Node'.
cause This TypeScript error occurs if you are iterating or accessing `children` directly on a generic `Node` type, especially after the v2.0.0 change, without first narrowing the type to `Root` or other node types that define `children`.fixImplement type guards or switch statements based on `node.type` to correctly narrow the `Node` type to `Root` or other specific types (e.g., `NodeType.Bold`, `NodeType.Italic`) before accessing properties like `children`.
Warnings
- breaking Version 3.0.0 introduced a breaking change requiring Node.js version 16 or greater due to the shift in shipped code from ES2015 to ES2021.
- breaking With v3.0.0, the package transitioned to ES Modules (ESM) builds. Projects using CommonJS (CJS) may encounter issues with `require()` statements or need to configure Node.js for ESM interoperability.
- breaking In v2.0.0, the TypeScript typing for the return type of the `parse` function changed from `Node` to `Root`. While `Node` previously encompassed `Root`, this is a breaking change for code that directly inferred or expected `Node` when specifically working with the root of the parsed tree.
- gotcha Prior to v3.0.2, the parser did not correctly support multiline quotes that omitted the `>>>` prefix, potentially leading to incorrect or incomplete parsing of such message blocks.
Install
-
npm install slack-message-parser -
yarn add slack-message-parser -
pnpm add slack-message-parser
Imports
- slackMessageParser
const slackMessageParser = require('slack-message-parser');import slackMessageParser from 'slack-message-parser';
- Node
const { Node } = require('slack-message-parser');import { Node } from 'slack-message-parser'; - NodeType
const { NodeType } = require('slack-message-parser');import { NodeType } from 'slack-message-parser';
Quickstart
import slackMessageParser, { Node, NodeType } from "slack-message-parser";
const tree = slackMessageParser("Slack *message* ~to~ _parse_");
// Write your own!
const toHTML = (node: Node): string => {
switch (node.type) {
case NodeType.Root:
return `<p>${node.children.map(toHTML).join("")}</p>`;
case NodeType.Text:
return node.text;
case NodeType.Bold:
return `<strong>${node.children.map(toHTML).join("")}</strong>`;
case NodeType.Italic:
return `<i>${node.children.map(toHTML).join("")}</i>`;
case NodeType.Strike:
return `<del>${node.children.map(toHTML).join("")}</del>`;
default:
// You can use `source` property, which every nodes have, to serialize unknown nodes as-is
return node.source;
}
};
console.log(toHTML(tree));
// Expected Output:
// '<p>Slack <strong>message</strong> <del>to</del> <i>parse</i></p>'