# How to Use TextMobject and Manage Fonts for Text Rendering in Manim

> Learn to use TextMobject in Manim to render text and manage fonts. Understand font resolution hierarchy for global, scene, and instance-level control.

- Repository: [Grant Sanderson/manim](https://github.com/3b1b/manim)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Manim renders vector-based text using the Pango library via `manimpango`, where the `Text` class (historically referred to as `TextMobject`) inherits from `MarkupText` in [`manimlib/mobject/svg/text_mobject.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/svg/text_mobject.py) and resolves fonts through a three-tier hierarchy of global configuration, scene-level overrides, and per-instance constructor arguments.**

The `3b1b/manim` repository (Grant Sanderson’s original animation engine) handles text rendering through a sophisticated SVG-based pipeline. Whether you are displaying mathematical explanations or UI labels, understanding how to use the `Text` class and manage font selection is essential for crisp, scalable typography in your animations.

## Understanding the Text Class Hierarchy

Manim’s text system is built on a chain of inheritance that converts strings into SVG paths. The core implementation lives in **[`manimlib/mobject/svg/text_mobject.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/svg/text_mobject.py)**.

### Text, MarkupText, and StringMobject

The hierarchy flows from `SVGMobject` down to concrete text classes:

1. **`StringMobject`** – Base class for string-based SVG mobjects.
2. **`MarkupText`** – Inherits from `StringMobject`. It builds an SVG by converting a Pango markup string via `markup_to_svg` (see lines [53‑62](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L53-L62)).
3. **`Text`** – Inherits from `MarkupText`. It overrides the markup parsing to treat input as plain text, escaping only the markup characters (see the overridden static methods at lines [21‑35](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L21-L35)).

This architecture means `Text` objects are ultimately collections of `VMobject` paths derived from font glyphs, allowing for standard Manim transforms like `Write`, `FadeIn`, and complex color mapping.

## Font Resolution and Configuration

Font selection in Manim operates through a cascading priority system defined in the `__init__` method of `MarkupText` around lines [68‑78](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L68-L78).

### Global Defaults in default_config.yml

The base font configuration resides in **[`manimlib/default_config.yml`](https://github.com/3b1b/manim/blob/main/manimlib/default_config.yml)** at lines [88‑90](https://github.com/3b1b/manim/blob/master/manimlib/default_config.yml#L88-L90):

```yaml
text:
  font: "Consolas"
  alignment: "LEFT"

```

By default, all `Text` objects render using **Consolas** unless overridden.

### Per-Scene and Instance Overrides

You can override fonts at two additional levels:

1. **Scene-level** – Modify `manim_config.text.font` at runtime or via a custom `--config_file`:

```python
from manimlib import *

config.text.font = "Times New Roman"

class Example(Scene):
    def construct(self):
        # This uses Times New Roman by default

        t = Text("Scene Default Font")
        self.add(t)

```

2. **Instance-level** – Pass `font="Font Name"` directly to the constructor. This takes highest priority (see line [75](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L75) where `self.font = font or text_config.font`):

```python
Text("Override Example", font="Arial")

```

## Registering Custom Font Files

Manim does not ship with every system font. To use a custom **TTF** or **OTF** file that is not installed system-wide, use the **`register_font`** context manager defined at lines [69‑99](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L69-L99) in the same file.

This context manager temporarily adds the font file to Pango’s search path:

```python
from manimlib import *

class CustomFontScene(Scene):
    def construct(self):
        with register_font("fonts/UbuntuMono-R.ttf"):
            # "Ubuntu Mono" must match the font family name inside the TTF

            text = Text(
                "Custom Font Rendering",
                font="Ubuntu Mono",
                t2f={"Custom": "Comic Sans MS"}  # Mix fonts within text

            )
        self.play(Write(text))

```

**Critical note:** The string passed to `font=` must match the **font family name** embedded in the TTF metadata, not the filename.

## Text Scaling and Alignment

### Scaling Calibration

The size of a `Text` object is calibrated so that a reference glyph `"0"` has a height of **1 Manim unit**. This scaling factor is calculated by `get_text_mob_scale_factor` at lines [103‑113](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L103-L113).

When you call `.scale(2)`, the text doubles in size relative to this calibrated baseline.

### Alignment Options

Horizontal alignment defaults to the config value (`text.alignment`) but can be overridden per object via the `alignment` parameter:

- `"LEFT"` (default)
- `"CENTER"`
- `"RIGHT"`

```python
Text("Right aligned", alignment="RIGHT").to_corner(DR)

```

For multiline text, control vertical spacing with `lsh` (line spacing height):

```python
Text("Line 1\nLine 2", lsh=1.5)  # 1.5x default spacing

```

## Styling Shortcuts for Text

The `Text` class supports dictionary-based styling that maps text selectors to visual properties. These are applied after SVG generation (see `get_configured_items` at lines [98‑116](https://github.com/3b1b/manim/blob/master/manimlib/mobject/svg/text_mobject.py#L98-L116)):

- **`t2c`** – Text to color
- **`t2f`** – Text to font
- **`t2g`** – Text to gradient
- **`t2s`** – Text to slant (ITALIC, NORMAL, OBLIQUE)
- **`t2w`** – Text to weight (BOLD, THIN, etc.)

```python
Text(
    "Colorful Bold Manim",
    t2c={"Colorful": BLUE, "Manim": RED},
    t2w={"Bold": BOLD},
    t2f={"Manim": "Times New Roman"}
)

```

## Summary

- **Inheritance chain**: `Text` → `MarkupText` → `StringMobject` in [`manimlib/mobject/svg/text_mobject.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/svg/text_mobject.py), converting strings to SVG paths via Pango.
- **Font resolution**: Three-tier priority system—global config ([`default_config.yml`](https://github.com/3b1b/manim/blob/main/default_config.yml)), scene override (`config.text.font`), and instance argument (`font="Name"`).
- **Custom fonts**: Use the `register_font` context manager to temporarily load TTF/OTF files not installed system-wide.
- **Scaling**: Reference glyph `"0"` equals 1 Manim unit; use `alignment` and `lsh` for positioning and line spacing.
- **Styling**: Apply `t2c`, `t2f`, `t2g`, `t2s`, and `t2w` dictionaries for per-word formatting.

## Frequently Asked Questions

### What is the difference between Text and TextMobject in Manim?

In the `3b1b/manim` repository (ManimGL), the modern class is **`Text`**, which inherits from `MarkupText`. Earlier versions and the community edition (ManimCE) historically used `TextMobject` for LaTeX-based text and `Text` for Pango-based rendering. In current ManimGL, `Text` is the standard class for plain text rendering using system fonts via Pango.

### How do I use a custom TTF font that is not installed on my system?

Wrap your `Text` instantiation in the **`register_font`** context manager imported from `manimlib.mobject.svg.text_mobject`. Pass the path to your `.ttf` or `.otf` file as the argument. Inside the context block, reference the font by its family name (as defined in the font metadata) in the `font` parameter of `Text`.

### Why is my text appearing as squares or not rendering correctly?

Squares typically indicate **missing glyph coverage** or **font not found**. Verify that the font name passed to `font=` exactly matches the family name in the font file metadata (not the filename). If using a custom font file, ensure you are using `register_font`. Additionally, check that `manimpango` and Pango are properly installed in your environment, as these are required for SVG text generation.

### How do I change the default font for all text in a scene?

Modify the **`config.text.font`** attribute before constructing your `Text` objects. You can set this in your scene’s `__init__` or at the module level: `config.text.font = "Arial"`. Alternatively, create a custom [`default_config.yml`](https://github.com/3b1b/manim/blob/main/default_config.yml) and pass it via the `--config_file` CLI argument to override the global defaults defined in [`manimlib/default_config.yml`](https://github.com/3b1b/manim/blob/main/manimlib/default_config.yml).