flutter_mathjax
A Flutter package for rendering LaTeX equations using MathJax v2 within a WebView. This package provides automatic line breaking, offline caching, and performance optimizations using image snapshots.
Features
- MathJax v2 Support: Renders LaTeX using the stable MathJax v2 engine.
- Automatic Line Breaking: Configured to automatically break long equations to fit the container width.
- Performance Optimization: Supports replacing the heavy WebView with a static image snapshot after rendering to reduce memory usage and improve scrolling performance (
imageCache: true). - Offline Caching: Automatically caches MathJax assets (JS, fonts) for fast subsequent loads and offline support. Assets are lazily loaded or served from a local zip for initial setup.
- Optimized App Size: Uses a compressed zip file for initial assets to minimize the package footprint while ensuring immediate availability.
- Hybrid Content: Supports mixing HTML with LaTeX.
Technical Decisions & Performance
Why MathJax v2?
We explicitly chose MathJax v2 over KaTeX or MathJax v3 because it currently offers superior automatic line-breaking capabilities on mobile devices. This ensures complex equations resize and wrap correctly on smaller screens.
Why No Localhost Server?
This package avoids using a local HTTP server (localhost) to serve assets. Localhost servers can be unstable on mobile devices (port conflicts, background restrictions) and a single failure could break all LaTeX rendering. Instead, we use a robust interception and caching mechanism to serve assets reliably.
Image Caching & Performance
By default, imageCache: true captures a static snapshot of the rendered LaTeX and replaces the heavy WebView. This offers significant benefits:
- Zero RAM usage per equation after rendering (images are lighter than WebViews).
- Native Interactions: Allows using the widget in Draggables, ListViews, and other interative layouts without the gesture conflicts common with PlatformViews.
- High Performance: Smooth scrolling even with hundreds of equations.
Important
When to disable imageCache:
Only use imageCache: true for pure LaTeX or simple text. If your content includes interactive HTML elements like images, videos, audio, or iframes, you MUST set imageCache: false. Snapshots are static images and will kill any interactivity within the HTML content.
Installation
Add this to your package's pubspec.yaml file:
dependencies:
flutter_mathjax: ^0.0.1
Note
This package relies on flutter_inappwebview, http, path_provider, and archive. These are standard, Battle-tested packages in the Flutter ecosystem that are stable and rarely introduce breaking changes.
Usage
1. Initialization
You must initialize the MathJaxManager to enable caching and asset management.
import 'package:flutter/material.dart';
import 'package:flutter_mathjax/flutter_mathjax.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize MathJaxManager
// Note: 'await' is only required if you need to render LaTeX immediately on the first screen.
// If your first screen doesn't have LaTeX, you can fire-and-forget this.
await MathJaxManager.inst.init();
runApp(const MyApp());
}
2. Basic Usage
Use the MathJaxView widget to render LaTeX strings.
import 'package:flutter_mathjax/flutter_mathjax.dart';
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: MathJaxView(
latex: r'$$ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$',
),
),
);
}
}
3. Rendering HTML with LaTeX
You can also pass HTML content containing MathJax delimiters.
MathJaxView(
latex: r'''
<p>Solve the quadratic equation:</p>
$$ ax^2 + bx + c = 0 $$
''',
)
Configuration
MathJaxView Properties
| Property | Type | Default | Description |
|---|---|---|---|
latex |
String |
Required | The LaTeX string or HTML content to render. |
height |
double? |
null |
Explicit height. If null, automatically calculates content height. |
width |
double? |
null |
Explicit width. |
imageCache |
bool |
true |
If true, captures a snapshot and replaces the WebView after rendering. |
placeholder |
Widget? |
null |
Widget to display while rendering. |
Caching
The MathJaxManager automatically intercepts requests to MathJax CDNs and caches the files locally. This ensures that after the first load, the equations will render instantly and available offline.
Requirements
- Android:
minSdkVersion 19or higher (required byflutter_inappwebview). - iOS: iOS 9.0 or higher.
Contributing
We welcome contributions! If you have ideas for new features, bug fixes, or performance improvements, please feel free to open a pull request. We are committed to maintaining and improving this library to serve the Flutter community.