Skip to content

Commit 2e258cd

Browse files
committed
feat: add web support
1 parent 579a9ed commit 2e258cd

40 files changed

Lines changed: 4559 additions & 584 deletions

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
# react-native-enriched-markdown
44

5-
`react-native-enriched-markdown` is a powerful React Native library that renders Markdown content as native text and provides a rich text input with Markdown output. It supports iOS, Android, and macOS, and requires the New Architecture (Fabric).
5+
`react-native-enriched-markdown` is a powerful React Native library that renders Markdown content as native text and provides a rich text input with Markdown output. It supports iOS, Android, macOS, and Web, and requires the New Architecture (Fabric) for native platforms.
66

77
### EnrichedMarkdownText
88

99
- ⚡ Fully native text rendering (no WebView)
10+
- 🌐 Web support via [react-native-web](https://necolas.github.io/react-native-web/) + [md4c](https://github.com/mity/md4c) compiled to WebAssembly
1011
- 🎯 High-performance Markdown parsing with [md4c](https://github.com/mity/md4c)
1112
- 📐 CommonMark standard compliant
1213
- 📊 GitHub Flavored Markdown (GFM)
@@ -56,21 +57,40 @@ We can help you build your next dream product –
5657
- [Other Events](docs/INPUT.md#other-events)
5758
- [Customizing Styles](docs/INPUT.md#customizing-enrichedmarkdowninput--styles)
5859
- [API Reference](#api-reference)
60+
- [Web Support](docs/WEB.md)
5961
- [macOS Support](docs/MACOS.md)
6062
- [Contributing](#contributing)
6163
- [Future Plans](#future-plans)
6264
- [License](#license)
6365

6466
## Prerequisites
6567

66-
- Supports iOS, Android, and macOS platforms
68+
**Native (iOS / Android / macOS)**
6769
- Requires [the React Native New Architecture (Fabric)](https://reactnative.dev/architecture/landing-page)
6870
- Supported React Native releases: `0.81`, `0.82`, `0.83`, and `0.84`
6971
- macOS support via [react-native-macos](https://github.com/microsoft/react-native-macos) `0.81+`
7072

73+
**Web**
74+
- Requires [`react-native-web`](https://necolas.github.io/react-native-web/) and Metro (or another bundler with `.web.tsx` platform resolution)
75+
- No New Architecture requirement — the web renderer runs entirely in JavaScript via WebAssembly
76+
- Only `EnrichedMarkdownText` is supported on web (`EnrichedMarkdownInput` is native-only)
77+
- LaTeX math requires the optional [`katex`](https://katex.org/) peer dependency
78+
7179
## Installation
7280

73-
### Bare React Native app
81+
### Web
82+
83+
No steps beyond having `react-native-web` configured. For LaTeX math, install the optional peer dependency:
84+
85+
```sh
86+
npm install katex
87+
# or
88+
yarn add katex
89+
```
90+
91+
See [Web Support](docs/WEB.md) for full setup details, supported features, and prop behaviour.
92+
93+
### Bare React Native app (iOS / Android)
7494

7595
#### 1. Install the library
7696

@@ -140,6 +160,10 @@ See [EnrichedMarkdownInput](docs/INPUT.md) for detailed documentation on usage e
140160
141161
See the [API Reference](docs/API_REFERENCE.md) for a detailed overview of all the props, methods, and events available.
142162
163+
## Web Support
164+
165+
See [Web Support](docs/WEB.md) for details on supported features, web-specific prop behaviour, and known limitations.
166+
143167
## macOS Support
144168
145169
`react-native-enriched-markdown` supports macOS via [react-native-macos](https://github.com/microsoft/react-native-macos). See [macOS Support](docs/MACOS.md) for details on macOS-specific features, known limitations, and the example app.
@@ -149,7 +173,7 @@ See the [API Reference](docs/API_REFERENCE.md) for a detailed overview of all th
149173
We're actively working on expanding the capabilities of `react-native-enriched-markdown`. Here's what's on the roadmap:
150174
151175
- `EnrichedMarkdownInput`: headings, lists, blockquotes, code blocks, mentions, inline images
152-
- Web implementation via `react-native-web`
176+
- `EnrichedMarkdownInput` web support
153177
- macOS: block math rendering, VoiceOver accessibility, tail fade-in animation
154178
155179
## Contributing

apps/web-example/app.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"expo": {
3+
"name": "EnrichedMarkdownWebExample",
4+
"slug": "enriched-markdown-web-example",
5+
"version": "1.0.0",
6+
"platforms": ["web"],
7+
"web": {
8+
"output": "single"
9+
}
10+
}
11+
}

apps/web-example/babel.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = function (api) {
2+
api.cache(true);
3+
return {
4+
presets: ['babel-preset-expo'],
5+
};
6+
};

apps/web-example/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import '@expo/metro-runtime';
2+
3+
import { registerRootComponent } from 'expo';
4+
import App from './src/App';
5+
6+
registerRootComponent(App);

apps/web-example/metro.config.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const { getDefaultConfig } = require('expo/metro-config');
2+
3+
const path = require('path');
4+
5+
const projectRoot = __dirname;
6+
const monorepoRoot = path.resolve(projectRoot, '../..');
7+
8+
const pkg = require('../../package.json');
9+
10+
const config = getDefaultConfig(projectRoot);
11+
12+
// Watch the monorepo root so Metro picks up changes to the library source.
13+
config.watchFolders = [monorepoRoot];
14+
15+
// Resolve node_modules from both the project and the monorepo root.
16+
config.resolver.nodeModulesPaths = [
17+
path.resolve(projectRoot, 'node_modules'),
18+
path.resolve(monorepoRoot, 'node_modules'),
19+
];
20+
21+
// Redirect the library's package name to its source entry point so that
22+
// Metro doesn't try to load the built output (./lib/module/index.js) which
23+
// is not committed to the repo. Use the platform-specific entry on web.
24+
const upstreamResolveRequest = config.resolver.resolveRequest;
25+
config.resolver.resolveRequest = (context, moduleName, platform) => {
26+
if (moduleName === pkg.name) {
27+
const entry = platform === 'web' ? 'src/index.web.tsx' : 'src/index.tsx';
28+
return {
29+
filePath: path.resolve(monorepoRoot, entry),
30+
type: 'sourceFile',
31+
};
32+
}
33+
if (upstreamResolveRequest) {
34+
return upstreamResolveRequest(context, moduleName, platform);
35+
}
36+
return context.resolveRequest(context, moduleName, platform);
37+
};
38+
39+
module.exports = config;

apps/web-example/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "react-native-enriched-markdown-web-example",
3+
"version": "0.0.1",
4+
"private": true,
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "expo start",
8+
"web": "expo start --web",
9+
"build:web": "expo export --platform web"
10+
},
11+
"dependencies": {
12+
"expo": "~55.0.0",
13+
"katex": "^0.16.44",
14+
"react": "19.2.3",
15+
"react-dom": "19.2.3",
16+
"react-native": "0.84.1",
17+
"react-native-enriched-markdown": "*",
18+
"react-native-web": "~0.19.13"
19+
},
20+
"devDependencies": {
21+
"@expo/metro-runtime": "~5.0.0",
22+
"@types/react": "^19.2.0",
23+
"babel-preset-expo": "~55.0.13",
24+
"typescript": "^5.9.2"
25+
}
26+
}

0 commit comments

Comments
 (0)