react-native-marked

repository·main·Indexed 43 days ago

https://github.com/gmsgowtham/react-native-marked

A Markdown renderer for React Native powered by marked.js, featuring built-in theming support and efficient rendering via FlatList. Version 8.3.0 provides a <Markdown /> component, the useMarkdown and useMarkdownWithComponents hooks, and support for custom Renderers and Tokenizers to extend parsing and rendering logic.

Tokens
17.7K
Snippets
53
Records
74
Agent score
54%

What's inside react-native-marked

  1. Overview of the react-native-marked API surface

    main

    The react-native-marked library provides several ways to render Markdown in React Native applications. The primary entry point is src/index.ts, which re-exports the following core components and hooks:

    • Markdown: The default component, which acts as a FlatList wrapper for efficient rendering.
    • useMarkdown: A hook for managing Markdown state and parsing.
    • useMarkdownWithComponents: A hook for rendering Markdown with custom React components.
    • Renderer: A component used for custom rendering logic.
    • ReactComponentRegistry & Provider: Used for managing and providing custom React components to the Markdown renderer.
    • Marked utilities: Re-exports MarkedHooks, MarkedTokenizer, and MarkedLexer from the underlying marked library.

    The core processing flow is: marked.lexer → Parser.tsx → RendererInterface → Theming (styles.ts).

  2. Supported Markdown elements

    main

    The library supports the following elements based on CommonMark:

    • Headings (1 to 6)
    • Paragraph
    • Emphasis (bold, italic, and strikethrough)
    • Link
    • Image
    • Blockquote
    • Inline Code
    • Code Block
    • List (ordered, unordered)
    • Horizontal Rule
    • Table
    • React Components (via useMarkdownWithComponents)

    Note: HTML is currently treated as plain text and is not rendered as HTML elements.

  3. Handle Images and SVGs in Markdown

    main

    The library provides specialized components for different media types:

    • SVGs: .svg URIs are automatically rendered using the MDSvg component.
    • Standard Images: Other image formats are rendered via the MDImage component.

    Both components use the markdown alt text (falling back to the title) as the accessibilityLabel for improved accessibility.

  4. Control appearance with theme and styles props

    main

    The appearance of the Markdown component is controlled by two complementary props:

    1. theme: Provides a palette of colors and spacing tokens. These are applied via the internal theme engine.
    2. styles: Provides direct React Native TextStyle, ViewStyle, or ImageStyle overrides for specific Markdown elements. styles take precedence over the theme.
  5. Choosing between Markdown APIs

    main

    The library provides three primary ways to consume markdown depending on your UI requirements:

    1. Markdown component: The easiest option. It acts as a drop-in FlatList wrapper, handling scrolling and virtualization automatically.
    2. useMarkdown hook: Use this when you need full control over the container, such as using a custom ScrollView, FlatList, or implementing your own virtualization logic.
    3. useMarkdownWithComponents hook: Use this when you need to embed interactive JSX components (like <Button /> or <InfoBox />) directly inside your markdown content.
  6. Run the documentation site locally

    main

    The documentation site uses Rspress (powered by Rspack) for development and building. You can manage the documentation lifecycle using the following yarn commands from the repository root:

    • yarn docs:dev: Starts a development server with Hot Module Replacement (HMR).
    • yarn docs:build: Generates a production build in the docs/doc_build directory.
    • yarn docs:preview: Previews the production build locally.
    yarn docs:dev      # HMR dev server
    yarn docs:build    # production build
    yarn docs:preview
  7. Create a custom renderer by subclassing Renderer

    main

    To customize how specific Markdown elements are rendered, subclass the Renderer class and override methods defined in the RendererInterface. This allows you to replace default React Native components with your own, such as using react-native-fast-image for images or applying custom styles to codespan elements.

    Important: Always use this.getKey() within your overridden methods to ensure stable React keys.

    import React, { type ReactNode, Fragment } from "react";
    import { Text, ScrollView, type TextStyle, type ImageStyle } from "react-native";
    import Markdown, { Renderer, type RendererInterface } from "react-native-marked";
    import FastImage from "react-native-fast-image";
    
    class CustomRenderer extends Renderer implements RendererInterface {
      codespan(text: string, _styles?: TextStyle): ReactNode {
        return (
          <Text key={this.getKey()} style={{ backgroundColor: "#ff0" }}>
            {text}
          </Text>
        );
      }
    
      image(uri: string, _alt?: string, _style?: ImageStyle): ReactNode {
        return (
          <FastImage
            key={this.getKey()}
            style={{ width: 200, height: 200 }}
            source={{ uri }}
            resizeMode={FastImage.resizeMode.contain}
          />
        );
      }
    }
    
    const renderer = new CustomRenderer();
    
    export default function App() {
      return <Markdown value={`'Hello'`} renderer={renderer} />;
    }
    
    // Hook variant
    function WithHook() {
      const els = useMarkdown("`Hello`", { renderer } as any);
      return <ScrollView>{els.map((e, i) => <Fragment key={i}>{e}</Fragment>)}</ScrollView>;
    }
  8. Run the local sample application

    main

    To explore the library in a real environment, you can run the local sample app located in examples/react-native-marked-sample. This sample is compatible with Expo 53 and React Native 0.79.4.

    Follow these steps to set it up:

    1. Navigate to the example directory.
    2. Install dependencies.
    3. Run the application for your target platform (Android, iOS, or Web).
    cd examples/react-native-marked-sample
    yarn install
    yarn android | yarn ios | yarn web
  9. Render Markdown using the Markdown component

    main

    The Markdown component is a FlatList wrapper and provides the simplest way to render markdown content in a React Native application. It accepts a markdown string via the value prop and allows for customization through styles, theme, and flatListProps.

    import * as React from "react";
    import Markdown from "react-native-marked";
    
    export default function Example() {
      return (
        <Markdown
          value={`# Hello world\n\n- item 1\n- item 2`}
          flatListProps={{ initialNumToRender: 8 }}
          styles={{
            h1: { color: "#111" },
            paragraph: { marginBottom: 12 },
          }}
          theme={{ colors: { text: "#222", background: "#fff" } }}
          baseUrl="https://example.com"
          selectable
        />
      );
    }