Markdown renderer for React Native powered by marked.js with built-in theming support
yarn add react-native-marked react-native-svgyarn add react-native-marked@6.0.7 react-native-svgimport * as React from "react";
import Markdown from "react-native-marked";
const ExampleComponent = () => {
  return (
    <Markdown
      value={`# Hello world`}
      flatListProps={{
        initialNumToRender: 8,
      }}
    />
  );
};
export default ExampleComponent;| Prop | Description | Type | Optional? | 
|---|---|---|---|
| value | Markdown value | string | false | 
| flatListProps | Props for customizing the underlying FlatList used | Omit<FlatListProps<ReactNode>, 'data' | 'renderItem' | 'horizontal'>( 'data', 'renderItem', and 'horizontal' props are omitted and cannot be overridden.) | 
true | 
| styles | Styles for parsed components | MarkedStyles | true | 
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | UserTheme | true | 
| baseUrl | A prefix url for any relative link | string | true | 
| renderer | Custom component Renderer | RendererInterface | true | 
useMarkdown hook will return list of elements that can be rendered using a list component of your choice.
import React, { Fragment } from "react";
import { ScrollView, useColorScheme } from "react-native";
import { useMarkdown, type useMarkdownHookOptions } from "react-native-marked";
const CustomComponent = () => {
  const colorScheme = useColorScheme();
  const options: useMarkdownHookOptions = {
    colorScheme
  }
  const elements = useMarkdown("# Hello world", options);
  return (
    <ScrollView>
      {elements.map((element, index) => {
        return <Fragment key={`demo_${index}`}>{element}</Fragment>
      })}
    </ScrollView>
  );
};| Option | Description | Type | Optional? | 
|---|---|---|---|
| colorScheme | Device color scheme ("dark" or "light") | ColorSchemeName | false | 
| styles | Styles for parsed components | MarkedStyles | true | 
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | UserTheme | true | 
| baseUrl | A prefix url for any relative link | string | true | 
| renderer | Custom component Renderer | RendererInterface | true | 
| tokenizer | Generate custom tokens | MarkedTokenizer | true | 
- Headings (1 to 6)
 - Paragraph
 - Emphasis (bold, italic, and strikethrough)
 - Link
 - Image
 - Blockquote
 - Inline Code
 - Code Block
 - List (ordered, unordered)
 - Horizontal Rule
 - Table
 - HTML
 
Ref: CommonMark
HTML will be treated as plain text. Please refer issue#290 for a potential solution
Custom components can be used to override elements, i.e. Code Highlighting, Fast Image integration
import React, { ReactNode, Fragment } from "react";
import { Text, ScrollView } from "react-native";
import type { ImageStyle, TextStyle } from "react-native";
import Markdown, { Renderer, useMarkdown } from "react-native-marked";
import type { RendererInterface } from "react-native-marked";
import FastImage from "react-native-fast-image";
class CustomRenderer extends Renderer implements RendererInterface {
  constructor() {
    super();
  }
  codespan(text: string, _styles?: TextStyle): ReactNode {
    return (
      <Text key={this.getKey()} style={{ backgroundColor: "#ff0000" }}>
        {text}
      </Text>
    );
  }
  image(uri: string, _alt?: string, _style?: ImageStyle): ReactNode {
    return (
      <FastImage
        key={this.getKey()}
        style={{ width: 200, height: 200 }}
        source={{ uri: uri }}
        resizeMode={FastImage.resizeMode.contain}
      />
    );
  }
}
const renderer = new CustomRenderer();
const ExampleComponent = () => {
  return (
    <Markdown
      value={"`Hello world`"}
      flatListProps={{
        initialNumToRender: 8,
      }}
      renderer={renderer}
    />
  );
};
// Alternate using hook
const ExampleComponentWithHook = () => {
  const elements = useMarkdown("`Hello world`", { renderer });
  return (
    <ScrollView>
      {elements.map((element, index) => {
        return <Fragment key={`demo_${index}`}>{element}</Fragment>
      })}
    </ScrollView>
  )
}
export default ExampleComponent;Please refer to RendererInterface for all the overrides
Note:
For
keyproperty for a component, you can use thegetKeymethod from Renderer class.
Overriding default codespan tokenizer to include LaTeX.
import React, { ReactNode } from "react";
import Markdown, { Renderer, MarkedTokenizer, MarkedLexer } from "react-native-marked";
import type { RendererInterface, CustomToken } from "react-native-marked";
class CustomTokenizer extends Tokenizer {
  codespan(src: string): Tokens.Codespan | undefined {
    const match = src.match(/^\$+([^\$\n]+?)\$+/);
    if (match?.[1]) {
      return {
        type: "codespan",
        raw: match[0],
        text: match[1].trim(),
      };
    }
    return super.codespan(src);
  }
}
class CustomRenderer extends Renderer implements RendererInterface {
  codespan(text: string, styles?: TextStyle): ReactNode {
    return (
      <Text style={styles} key={"key-1"}>
        {text}
      </Text>
    )
  }
}
const renderer = new CustomRenderer();
const tokenizer = new CustomTokenizer();
const ExampleComponent = () => {
  return (
    <Markdown
      value={"$ latex code $\n\n` other code `"}
      flatListProps={{
        initialNumToRender: 8,
      }}
      renderer={renderer}
      tokenizer={tokenizer}
    />
  );
};| Dark Theme | Light Theme | 
|---|---|
![]()  | 
![]()  | 
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library


