react-native-markdown-display is the actively maintained library for rendering Markdown in React Native, and it is safe to use as long as you control what happens when the Markdown comes from an untrusted source. The security question with react-native-markdown-display is not whether the package itself is vulnerable but how you handle links, custom rules, and any HTML when the content is user-supplied.
If you searched for a "react native markdown renderer," you probably landed on the older react-native-markdown-renderer package first. That one is unmaintained; react-native-markdown-display is its widely used successor and the one you should build on.
Prefer react-native-markdown-display over the old renderer
The original react-native-markdown-renderer has not seen meaningful updates in years. Using an abandoned rendering library for a format as adversarial as Markdown is a slow-motion risk: no upstream fixes, no compatibility with current React Native, and no one to report a problem to. Migrate to the maintained package:
npm install react-native-markdown-display
import Markdown from 'react-native-markdown-display';
export function Note({ text }) {
return <Markdown>{text}</Markdown>;
}
For static, developer-authored content this is all you need and there is little to worry about. The security work begins the moment text comes from a user, an API, or a chat message.
Treat user-supplied Markdown as untrusted input
React Native does not render into a browser DOM, so the classic <script> injection of web XSS does not apply directly. That does not make rendered Markdown safe by default. The realistic risks are:
- Dangerous link schemes: a Markdown link like
[tap me](javascript:...)or a custom scheme can, if you pass it straight to a handler, trigger unexpected navigation or deep-link behavior. - Overriding rules: the library lets you supply custom render rules, and a careless custom rule can reintroduce unsafe behavior the defaults avoided.
- Resource abuse: pathological Markdown (deeply nested structures, enormous documents) can degrade rendering performance.
The mitigation is to intercept the parts that touch the outside world rather than trusting the input.
Validate links before opening them
The most common footgun is the link handler. react-native-markdown-display lets you supply onLinkPress, which is exactly where you enforce an allowlist of schemes:
import Markdown from 'react-native-markdown-display';
import { Linking } from 'react-native';
const SAFE_SCHEMES = ['https:', 'mailto:'];
function onLinkPress(url) {
try {
const scheme = new URL(url).protocol;
if (!SAFE_SCHEMES.includes(scheme)) {
return false; // block anything not explicitly allowed
}
Linking.openURL(url);
} catch {
return false;
}
return false; // we handled it; stop default handling
}
<Markdown onLinkPress={onLinkPress}>{untrustedText}</Markdown>
Allowlisting https: and mailto: and rejecting everything else stops javascript:, custom app schemes, and other surprises from being handed to the OS. Never open a URL from untrusted Markdown without checking its scheme first.
Be careful with HTML and custom rules
Markdown can embed raw HTML. Whether that HTML does anything depends on your rendering setup, but the safe default is to not attempt to render arbitrary embedded HTML from untrusted content at all. If a feature needs it, sanitize the input on the server against a strict allowlist before it ever reaches the device, where you have less control and no easy patching.
Similarly, if you override render rules to add custom components (images, mentions, embeds), audit each rule the way you would audit any code that handles untrusted input. A custom image rule that fetches arbitrary URLs, for example, can leak the user's IP to a server the attacker controls.
Cap the size and depth of what you render
Denial-of-service through pathological input is easy to overlook on mobile. Before rendering user content, enforce a reasonable length limit and reject documents that are implausibly large. This is cheap and prevents a hostile message from freezing the UI thread during parsing.
Keep the dependency current
Because this library handles untrusted text directly, keeping it patched matters more than for a purely presentational component. Pin it in your lockfile, run npm audit in CI, and bump it when advisories or releases land. An SCA tool can track react-native-markdown-display along with its dependency chain and flag a stale or vulnerable version, including the abandoned react-native-markdown-renderer if a corner of your app still imports it.
FAQ
Is react-native-markdown-display safe to use?
Yes, it is the maintained library for rendering Markdown in React Native. It is safe for developer-authored content out of the box. For user-supplied Markdown, you need to validate link schemes, be careful with custom rules, and cap input size.
What is the difference from react-native-markdown-renderer?
react-native-markdown-renderer is an older, unmaintained package. react-native-markdown-display is its actively maintained successor. If you are starting fresh or still on the old renderer, use react-native-markdown-display.
Can markdown cause XSS in React Native?
Not classic browser XSS, since React Native has no DOM. The real risks are dangerous link schemes (like javascript:), unsafe custom render rules, and embedded HTML. Validate links in onLinkPress and sanitize untrusted content server-side.
How do I safely handle links in rendered markdown?
Supply an onLinkPress handler that parses the URL, allowlists safe schemes such as https: and mailto:, and rejects everything else before calling Linking.openURL. Never open an untrusted link without checking its scheme.