@expensify/react-native-live-markdown

中文文档
0.1.372发布于 2026/11/11MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 11.8万

Drop-in replacement for React Native's TextInput component with Markdown formatting.

原始使用文档
文档目录11 节
  1. Features
  2. Installation
  3. Usage
  4. Styling
  5. Parsing logic
  6. Markdown flavors support
  7. API reference
  8. Compatibility
  9. React Native compatibility
  10. react-native-worklets compatibility
  11. License
@expensify/react-native-live-markdown

Features

  • ⚛️ Drop-in replacement for <TextInput> component
  • ⌨️ Live synchronous formatting on every keystroke
  • ⚡ Fully native experience (selection, spellcheck, autocomplete)
  • 🔧 Customizable logic
  • 🎨 Customizable styles
  • 🌐 Universal support (Android, iOS, web)
  • 🏗️ Supports only the New Architecture

Installation

First, install the library from npm with the package manager of your choice:

yarn add @expensify/react-native-live-markdown react-native-worklets expensify-common [email protected]
npm install @expensify/react-native-live-markdown react-native-worklets expensify-common [email protected] --save
npx expo install @expensify/react-native-live-markdown react-native-worklets expensify-common [email protected]

React Native Live Markdown requires react-native-worklets 0.7.0 or newer as well as expensify-common 2.0.207 or newer and html-entities 2.5.3 exactly if using the default built-in ExpensiMark parser.

[!IMPORTANT] Please follow the react-native-worklets Getting Started guide to avoid issues.

Then, install the iOS dependencies with CocoaPods:

cd ios && bundler install && bundler exec pod install

The library includes native code so you will need to re-build the native app.

[!NOTE] The library does not support Expo Go, you will need to setup Expo Dev Client (see here).

Usage

import {MarkdownTextInput, parseExpensiMark} from '@expensify/react-native-live-markdown';
import React from 'react';

export default function App() {
  const [text, setText] = React.useState('Hello, *world*!');

  return (
    <MarkdownTextInput
      value={text}
      onChangeText={setText}
      parser={parseExpensiMark}
    />
  );
}

The built-in parseExpensiMark parser accepts an optional maximum input length. It defaults to 4,000 characters and returns no formatting ranges when the input is longer than the configured limit. To use a different limit, wrap the parser in a worklet function:

function parser(input: string) {
  'worklet';

  return parseExpensiMark(input, 5000);
}

Styling

MarkdownTextInput can be styled using style prop just like regular TextInput component.

It is also possible to customize the styling of the formatted contents of MarkdownTextInput component. The style object supports all color representations from React Native including PlatformColor and DynamicColorIOS according to the color reference. Currently, a limited set of styles is customizable but this is subject to change in the future.

import type {MarkdownStyle} from '@expensify/react-native-live-markdown';

const FONT_FAMILY_MONOSPACE = Platform.select({
  ios: 'Courier',
  default: 'monospace',
});

const FONT_FAMILY_EMOJI = Platform.select({
  ios: 'System',
  android: 'Noto Color Emoji',
  default: 'System, Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji',
});

const markdownStyle: MarkdownStyle = {
  syntax: {
    color: 'gray',
  },
  link: {
    color: 'blue',
  },
  h1: {
    fontSize: 25,
  },
  emoji: {
    fontSize: 20,
    fontFamily: FONT_FAMILY_EMOJI,
  },
  blockquote: {
    borderColor: 'gray',
    borderWidth: 6,
    marginLeft: 6,
    paddingLeft: 6,
  },
  code: {
    fontFamily: FONT_FAMILY_MONOSPACE,
    fontSize: 20,
    color: 'black',
    backgroundColor: 'lightgray',
  },
  pre: {
    fontFamily: FONT_FAMILY_MONOSPACE,
    fontSize: 20,
    color: 'black',
    backgroundColor: 'lightgray',
  },
  mentionHere: {
    color: 'green',
    backgroundColor: 'lime',
  },
  mentionUser: {
    color: 'blue',
    backgroundColor: 'cyan',
  },
};

The style object can be passed to multiple MarkdownTextInput components using markdownStyle prop:

<MarkdownTextInput
  value={text}
  onChangeText={setText}
  style={styles.input}
  markdownStyle={markdownStyle}
/>

[!TIP] We recommend to store the style object outside of a component body or memoize the style object with React.useMemo.

Parsing logic

MarkdownTextInput behavior can be customized via parser property. Parser is a function that accepts a plaintext string and returns an array of MarkdownRange objects:

interface MarkdownRange {
  type: MarkdownType;
  start: number;
  length: number;
  depth?: number;
}

Currently, only the following types are supported:

type MarkdownType = 'bold' | 'italic' | 'strikethrough' | 'emoji' | 'mention-here' | 'mention-user' | 'mention-report' | 'link' | 'code' | 'pre' | 'blockquote' | 'h1' | 'syntax';

Parser needs to be marked as a worklet because it's executed on the UI thread as the user types.

Here's a sample function that parses all substrings located between two asterisks as bold text:

function parser(input: string) {
  'worklet';

  const ranges = [];
  const regexp = /\*(.*?)\*/g;
  let match;
  while ((match = regexp.exec(input)) !== null) {
    ranges.push({start: match.index, length: 1, type: 'syntax'});
    ranges.push({start: match.index + 1, length: match[1]!.length, type: 'bold'});
    ranges.push({start: match.index + 1 + match[1]!.length, length: 1, type: 'syntax'});
  }
  return ranges;
}

[!TIP] We recommend to store the parser function outside of a component body or memoize the parser function with React.useMemo.

Markdown flavors support

Currently, react-native-live-markdown supports only ExpensiMark flavor out-of-the-box. You can customize the behavior by passing a custom parser worklet function via the parser prop, as detailed in the Parsing logic section.

API reference

MarkdownTextInput inherits all props of React Native's TextInput component as well as introduces the following properties:

PropTypeDefaultNote
parser(value: string) => MarkdownRange[]undefinedA function that parses the current value and returns an array of ranges.
markdownStyleMarkdownStyleundefinedAdds custom styling to Markdown text. The provided value is merged with default style object. See Styling for more information.

Compatibility

react-native-live-markdown supports only latest React Native minor releases with the New Architecture enabled.

React Native compatibility

0.730.740.750.760.770.780.790.800.810.820.830.840.850.860.870.88
0.1.362+❌❌❌❌❌❌✅✅✅✅✅✅✅✅✅✅
0.1.331 – 0.1.361❌❌❌❌❌❌✅✅✅✅✅✅✅✅❌❌
0.1.321 – 0.1.330❌❌❌❌❌❌✅✅✅✅✅✅✅❌❌❌
0.1.304 - 0.1.320❌❌❌❌✅✅✅✅✅❌❌❌❌❌❌❌
0.1.297 – 0.1.303❌❌❌❌✅✅✅✅❌❌❌❌❌❌❌❌
0.1.260 – 0.1.296❌❌❌❌✅✅✅❌❌❌❌❌❌❌❌❌
0.1.256 – 0.1.259❌❌❌❌✅❌❌❌❌❌❌❌❌❌❌❌
0.1.248 – 0.1.255❌❌❌✅✅❌❌❌❌❌❌❌❌❌❌❌
0.1.235 – 0.1.247❌❌✅✅✅❌❌❌❌❌❌❌❌❌❌❌
0.1.141 – 0.1.234❌❌✅✅❌❌❌❌❌❌❌❌❌❌❌❌
0.1.129 – 0.1.140❌❌✅❌❌❌❌❌❌❌❌❌❌❌❌❌
0.1.122 – 0.1.128❌✅❌❌❌❌❌❌❌❌❌❌❌❌❌❌
0.1.15 – 0.1.121✅❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌

react-native-worklets compatibility

0.6.x0.7.x0.8.x0.9.x0.10.2 – 0.11.x0.12.x0.13.x
0.1.343+❌✅✅✅✅✅✅
0.1.333 – 0.1.342❌✅✅✅✅❌❌
0.1.321 – 0.1.332❌✅✅✅❌❌❌
0.1.308 – 0.1.320✅❌❌❌❌❌❌

License

MIT


Brought to you by Software Mansion + Expensify

版本与发布记录

@expensify/react-native-live-markdown 共发布 358 个版本,首次发布于 2024/02/08;过去 12 个月发布了 57 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.372latest2026/11/112 天前
0.1.3712026/11/058 天前
0.1.3702026/11/0410 天前
0.1.3692026/11/0310 天前
0.1.3682026/11/0211 天前
0.1.3672026/11/0211 天前

关于 @expensify/react-native-live-markdown 的常见问题

@expensify/react-native-live-markdown 是什么?

Drop-in replacement for React Native's TextInput component with Markdown formatting.

如何安装 @expensify/react-native-live-markdown?

在项目目录运行 npm install @expensify/react-native-live-markdown,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(*)、react-native(*)、expensify-common(>=2.0.207)、react-native-worklets(>=0.7.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@expensify/react-native-live-markdown 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@expensify/react-native-live-markdown 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@expensify/react-native-live-markdown 可以商用吗?

@expensify/react-native-live-markdown 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@expensify/react-native-live-markdown 的下载量有多少?

根据 npm 官方下载统计,@expensify/react-native-live-markdown 在 2026/10/14 – 2026/11/12 这 30 天内被下载 118,099 次,日均约 3,937 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@expensify/react-native-live-markdown 还在维护吗?

最新版本 0.1.372 发布于 2026/11/11(2 天前);至今共发布 358 个版本,其中过去 12 个月发布了 57 个;首次发布于 2024/02/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。