Markdown renderer for React Native powered by marked.js
npm install react-native-marked




Markdown renderer for React Native powered by
marked.js with built-in theming support
#### For React Native 0.76 and above, please use the latest version.
``sh`
yarn add react-native-marked react-native-svg
#### For React Native 0.75 and below, please use version 6.
`sh`
yarn add react-native-marked@6.0.7 react-native-svg
`tsx
import * as React from "react";
import Markdown from "react-native-marked";
const ExampleComponent = () => {
return (
}
flatListProps={{
initialNumToRender: 8,
}}
/>
);
};
export default ExampleComponent;
`
#### Props
| Prop | Description | Type | Optional? |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| value | Markdown value | string | false |
| flatListProps | Props for customizing the underlying FlatList used | Omit'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 |
| hooks | Hooks run during parsing to transform tokens | Marked Hooks | true |
useMarkdown hook will return list of elements that can be rendered using a list component of your choice.
`tsx
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 (
{elements.map((element, index) => {
return }>{element}
})}
);
};
`
#### Options
| 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
| hooks | Hooks run during parsing to transform tokens |
Marked Hooks | true |
- CodeSandbox: https://codesandbox.io/s/react-native-marked-l2hpi3?file=/src/App.js
- [x] Headings (1 to 6)
- [x] Paragraph
- [x] Emphasis (bold, italic, and strikethrough)
- [x] Link
- [x] Image
- [x] Blockquote
- [x] Inline Code
- [x] Code Block
- [x] List (ordered, unordered)
- [x] Horizontal Rule
- [x] Table
- [x] React Components (via useMarkdownWithComponents)
- [ ] HTML
Ref: CommonMark
> HTML will be treated as plain text. Please refer issue#290 for a potential solution
You can embed React components directly in your markdown using JSX-style syntax. This is useful for adding interactive elements like buttons, custom info boxes, or any other React component.
`tsx
import React, { Fragment } from "react";
import { Pressable, ScrollView, Text, View } from "react-native";
import {
ReactComponentRegistryProvider,
useMarkdownWithComponents,
type ReactComponentRegistry,
} from "react-native-marked";
// Define your components
const components: ReactComponentRegistry = {
Button: ({ props }) => (
),
InfoBox: ({ props, children }) => (
{props.title &&
),
};
const markdown =
Click the button below:
This is an info box with markdown content.;
function MarkdownContent() {
const elements = useMarkdownWithComponents(markdown);
return (
{elements.map((element, index) => (
))}
);
}
export default function App() {
return (
);
}
`
#### Component Syntax
- Self-closing:
- With children: "value"
- Props: Supports string (), number ({42}), and boolean ({true}) props
#### Component Registry
Components must be registered via ReactComponentRegistryProvider. Unregistered components are automatically removed from the output.
> Custom components can be used to override elements, i.e. Code Highlighting, Fast Image integration
#### Example
`tsx
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}
);
}
image(uri: string, _alt?: string, _style?: ImageStyle): ReactNode {
return (
style={{ width: 200, height: 200 }}
source={{ uri: uri }}
resizeMode={FastImage.resizeMode.contain}
/>
);
}
}
const renderer = new CustomRenderer();
const ExampleComponent = () => {
return (
"}
flatListProps={{
initialNumToRender: 8,
}}
renderer={renderer}
/>
);
};
// Alternate using hook
const ExampleComponentWithHook = () => {
const elements = useMarkdown("Hello world", { renderer });
return (
{elements.map((element, index) => {
return }>{element}
})}
)
}
export default ExampleComponent;
`
> Please refer to RendererInterface for all the overrides
> Note:
>
> For key property for a component, you can use the getKey method from Renderer class.
#### Example
Overriding default codespan tokenizer to include LaTeX.
`tsx
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}
)
}
}
const renderer = new CustomRenderer();
const tokenizer = new CustomTokenizer();
const ExampleComponent = () => {
return (
"}``
flatListProps={{
initialNumToRender: 8,
}}
renderer={renderer}
tokenizer={tokenizer}
/>
);
};
#### Example
| Dark Theme | Light Theme |
|:-------------------------------------------------------------:|:----------------------------------------------------------------:|
| !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
- Marked
- @jsamr/react-native-li
- react-native-reanimated-table
- react-native-svg
- svg-parser
- github-slugger
- html-entities