Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/shopify/react-native-skia/llms.txt

Use this file to discover all available pages before exploring further.

React Native Skia provides powerful text rendering capabilities with support for custom fonts, text paths, glyphs, and paragraphs.

Text Component

Renders text at a specific position.
import { Canvas, Text, matchFont } from "@shopify/react-native-skia";

const font = matchFont({
  fontFamily: "Helvetica",
  fontSize: 24,
  fontWeight: "bold",
});

<Canvas style={{ flex: 1 }}>
  <Text x={50} y={100} text="Hello, Skia!" font={font} color="black" />
</Canvas>

Props

text
string
required
The text string to render
x
number
required
X-coordinate of the text baseline start
y
number
required
Y-coordinate of the text baseline
font
SkFont
required
Font object created with matchFont() or Skia.Font()
color
Color
Text color

Creating Fonts

Using matchFont

Match system fonts:
import { matchFont } from "@shopify/react-native-skia";

const regularFont = matchFont({
  fontFamily: "Arial",
  fontSize: 16,
});

const boldFont = matchFont({
  fontFamily: "Arial",
  fontSize: 16,
  fontWeight: "bold",
});

const italicFont = matchFont({
  fontFamily: "Arial",
  fontSize: 16,
  fontStyle: "italic",
});

Loading Custom Fonts

Use the useFonts hook:
import { useFonts, matchFont } from "@shopify/react-native-skia";

export default function CustomFontExample() {
  const fontsLoaded = useFonts({
    "Roboto-Regular": [require("./fonts/Roboto-Regular.ttf")],
    "Roboto-Bold": [require("./fonts/Roboto-Bold.ttf")],
  });
  
  const font = matchFont({
    fontFamily: "Roboto",
    fontSize: 20,
  });
  
  if (!fontsLoaded) return null;
  
  return (
    <Canvas style={{ flex: 1 }}>
      <Text x={50} y={100} text="Custom Font" font={font} />
    </Canvas>
  );
}

Imperative Font Creation

import { Skia, FontStyle } from "@shopify/react-native-skia";

const typeface = Skia.Typeface.MakeFreeTypeFaceFromData(
  require("./fonts/MyFont.ttf")
);

const font = Skia.Font(typeface, 24);

TextPath

Renders text along a path.
import { Canvas, TextPath, Path, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 20 });
const path = "M 50 150 Q 150 50 250 150";

<Canvas style={{ flex: 1 }}>
  <Path path={path} style="stroke" strokeWidth={1} color="#ccc" />
  <TextPath
    text="Text along a curved path"
    path={path}
    font={font}
    color="blue"
  />
</Canvas>

Props

text
string
required
The text to render
path
string | SkPath
required
The path to follow
font
SkFont
required
Font to use
initialOffset
number
default:"0"
Offset along the path where text starts

Glyphs

Render individual glyphs with precise positioning.
import { Canvas, Glyphs, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 32 });
const glyphIDs = font.getGlyphIDs("Hello");

const glyphs = glyphIDs.map((id, i) => ({
  id,
  pos: { x: 50 + i * 25, y: 100 },
}));

<Canvas style={{ flex: 1 }}>
  <Glyphs glyphs={glyphs} x={0} y={0} font={font} color="purple" />
</Canvas>

Props

glyphs
Glyph[]
required
Array of glyph objects with { id: number, pos: { x: number, y: number } }
x
number
required
X offset for all glyphs
y
number
required
Y offset for all glyphs
font
SkFont
required
Font containing the glyphs

TextBlob

Render pre-shaped text for better performance.
import { Canvas, TextBlob, Skia, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 24 });
const textBlob = Skia.TextBlob.MakeFromText("Optimized Text", font);

<Canvas style={{ flex: 1 }}>
  <TextBlob blob={textBlob} x={50} y={100} color="green" />
</Canvas>

Props

blob
SkTextBlob
required
Pre-created text blob
x
number
required
X-coordinate
y
number
required
Y-coordinate

Paragraph

Render multi-line text with advanced layout.
import { Canvas, Paragraph, Skia, useFonts } from "@shopify/react-native-skia";

export default function ParagraphExample() {
  const fontsLoaded = useFonts({
    Roboto: [require("./Roboto-Regular.ttf")],
  });
  
  if (!fontsLoaded) return null;
  
  const paragraphStyle = {
    textAlign: TextAlign.Left,
  };
  
  const textStyle = {
    color: Skia.Color("black"),
    fontFamilies: ["Roboto"],
    fontSize: 16,
  };
  
  const paragraph = Skia.ParagraphBuilder.Make(paragraphStyle)
    .pushStyle(textStyle)
    .addText("This is a paragraph with automatic line wrapping. ")
    .addText("It can contain multiple lines and styles.")
    .pop()
    .build();
  
  paragraph.layout(250); // Max width
  
  return (
    <Canvas style={{ flex: 1 }}>
      <Paragraph paragraph={paragraph} x={50} y={50} width={250} />
    </Canvas>
  );
}

Font Metrics

Get measurements from fonts:
const font = matchFont({ fontSize: 24 });

// Get text width
const width = font.getTextWidth("Hello");

// Get bounding box
const bounds = font.measureText("Hello");
console.log(bounds); // { x, y, width, height }

// Get font metrics
const metrics = font.getMetrics();
console.log(metrics); // { ascent, descent, leading }

// Get glyph IDs
const glyphIDs = font.getGlyphIDs("Hello");

// Get glyph widths
const widths = font.getGlyphWidths(glyphIDs);

Text Effects

Gradient Text

import { Canvas, Text, LinearGradient, vec, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 48, fontWeight: "bold" });

<Canvas style={{ flex: 1 }}>
  <Text x={50} y={100} text="GRADIENT" font={font}>
    <LinearGradient
      start={vec(0, 0)}
      end={vec(300, 0)}
      colors={["#FF0080", "#7928CA", "#0070F3"]}
    />
  </Text>
</Canvas>

Stroked Text

const font = matchFont({ fontSize: 48, fontWeight: "bold" });

<Canvas style={{ flex: 1 }}>
  {/* Outline */}
  <Text
    x={50}
    y={100}
    text="OUTLINE"
    font={font}
    color="blue"
    style="stroke"
    strokeWidth={2}
  />
  {/* Fill */}
  <Text x={50} y={100} text="OUTLINE" font={font} color="white" />
</Canvas>

Shadow Text

import { Canvas, Text, Shadow, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 36 });

<Canvas style={{ flex: 1 }}>
  <Text x={50} y={100} text="Shadowed" font={font} color="black">
    <Shadow dx={2} dy={2} blur={4} color="rgba(0,0,0,0.5)" />
  </Text>
</Canvas>

Performance Tips

  • Use TextBlob for static text that doesn’t change
  • Load fonts once and reuse font objects
  • Use useMemo to cache font creation
  • Avoid creating new font instances in render
  • For dynamic text, consider using the simpler Text component

Font Styling Options

const font = matchFont({
  fontFamily: "System",
  fontSize: 20,
  fontStyle: "normal" | "italic",
  fontWeight: "normal" | "bold" | 100-900,
});