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 19 or higher (required by flutter_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.

Libraries

flutter_mathjax