CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo-font

Load fonts at runtime and use them in React Native components.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

font-utils.mddocs/

Font Utilities

Utility functions for advanced font operations including text rendering to images. Provides platform-specific functionality for creating images from text with custom fonts.

Capabilities

Render Text to Image

Create images with custom text and font styling (iOS and Android only).

/**
 * Creates an image with provided text using specified font and styling options
 * @param glyphs - Text content to be rendered as an image
 * @param options - Rendering configuration options
 * @returns Promise resolving to image result with URI, dimensions
 */
function renderToImageAsync(
  glyphs: string,
  options?: RenderToImageOptions
): Promise<RenderToImageResult>;

interface RenderToImageOptions {
  /** Font family name (must be loaded or system font) */
  fontFamily?: string;
  /** Font size in points */
  size?: number;
  /** Text color (CSS color string or React Native color format) */
  color?: string;
}

interface RenderToImageResult {
  /** File URI to the generated image */
  uri: string;
  /** Image width in pixels */
  width: number;
  /** Image height in pixels */
  height: number;
}

Usage Examples:

import { renderToImageAsync, loadAsync } from 'expo-font';

// Simple text to image with default styling
async function createSimpleTextImage() {
  const result = await renderToImageAsync('Hello World!');
  
  console.log('Image created:', result.uri);
  console.log('Dimensions:', result.width, 'x', result.height);
  
  // Use the image URI in an Image component
  return <Image source={{ uri: result.uri }} />;
}

// Custom styling with loaded font
async function createStyledTextImage() {
  // First load a custom font
  await loadAsync({
    'CustomFont': require('./assets/fonts/CustomFont.ttf')
  });

  // Create image with custom styling
  const result = await renderToImageAsync('Styled Text', {
    fontFamily: 'CustomFont',
    size: 48,
    color: '#ff6b6b'
  });

  return (
    <Image 
      source={{ uri: result.uri }} 
      style={{ width: result.width, height: result.height }}
    />
  );
}

// Dynamic text image generation
async function createDynamicTextImage(text: string, fontSize: number) {
  const result = await renderToImageAsync(text, {
    fontFamily: 'System', // Use system font
    size: fontSize,
    color: 'rgba(0, 0, 0, 0.8)' // Semi-transparent black
  });

  return result;
}

// Error handling
async function createTextImageWithErrorHandling(text: string) {
  try {
    const result = await renderToImageAsync(text, {
      fontFamily: 'NonexistentFont', // This will fall back to system font
      size: 24,
      color: '#333333'
    });
    return result;
  } catch (error) {
    console.error('Failed to create text image:', error);
    // Fallback: use default styling
    return await renderToImageAsync(text);
  }
}

Advanced Use Cases

import { renderToImageAsync } from 'expo-font';
import { shareAsync } from 'expo-sharing';
import { manipulateAsync, SaveFormat } from 'expo-image-manipulator';

// Create shareable text images
async function createShareableQuote(quote: string, author: string) {
  // Create main quote image
  const quoteImage = await renderToImageAsync(`"${quote}"`, {
    fontFamily: 'serif',
    size: 32,
    color: '#2c3e50'
  });

  // Create author attribution
  const authorImage = await renderToImageAsync(`— ${author}`, {
    fontFamily: 'sans-serif',
    size: 18,
    color: '#7f8c8d'
  });

  // You could combine these images using image manipulation libraries
  // Then share the result
  await shareAsync(quoteImage.uri);
}

// Generate text-based watermarks
async function createWatermark(text: string) {
  const watermark = await renderToImageAsync(text, {
    fontFamily: 'monospace',
    size: 14,
    color: 'rgba(255, 255, 255, 0.3)' // Semi-transparent white
  });

  return watermark;
}

// Create text badges or labels
async function createBadge(label: string, color: string) {
  return await renderToImageAsync(label.toUpperCase(), {
    fontFamily: 'sans-serif-medium',
    size: 12,
    color: color
  });
}

// Generate text for accessibility purposes
async function createAltTextImage(altText: string) {
  return await renderToImageAsync(altText, {
    fontFamily: 'sans-serif',
    size: 16,
    color: '#000000'
  });
}

Integration with File System

import { renderToImageAsync } from 'expo-font';
import * as FileSystem from 'expo-file-system';

// Save rendered text image to device storage
async function saveTextImageToDevice(text: string, filename: string) {
  // Render text to image
  const textImage = await renderToImageAsync(text, {
    fontFamily: 'sans-serif',
    size: 24,
    color: '#000000'
  });

  // Define save location
  const fileUri = `${FileSystem.documentDirectory}${filename}.png`;

  // Copy from temporary location to permanent storage
  await FileSystem.copyAsync({
    from: textImage.uri,
    to: fileUri
  });

  console.log('Text image saved to:', fileUri);
  return { ...textImage, uri: fileUri };
}

// Create and cache text images
async function createCachedTextImage(text: string, cacheKey: string) {
  const cacheDir = `${FileSystem.cacheDirectory}text-images/`;
  const cachedPath = `${cacheDir}${cacheKey}.png`;

  // Check if cached version exists
  const cacheInfo = await FileSystem.getInfoAsync(cachedPath);
  if (cacheInfo.exists) {
    const size = await FileSystem.readAsStringAsync(
      `${cacheDir}${cacheKey}.json`
    );
    const dimensions = JSON.parse(size);
    return { uri: cachedPath, ...dimensions };
  }

  // Create new image
  const result = await renderToImageAsync(text, {
    size: 20,
    color: '#333'
  });

  // Ensure cache directory exists
  await FileSystem.makeDirectoryAsync(cacheDir, { intermediates: true });

  // Save to cache
  await FileSystem.copyAsync({ from: result.uri, to: cachedPath });
  await FileSystem.writeAsStringAsync(
    `${cacheDir}${cacheKey}.json`,
    JSON.stringify({ width: result.width, height: result.height })
  );

  return { ...result, uri: cachedPath };
}

Platform Support and Limitations

Supported Platforms

  • iOS: Full support with native text rendering
  • Android: Full support with native text rendering
  • Web: Not supported (function will throw UnavailabilityError)

Font Requirements

  • Custom fonts must be loaded using loadAsync() before use
  • System fonts are available immediately:
    • iOS: 'System', 'Helvetica', 'Times', 'Courier', etc.
    • Android: 'sans-serif', 'serif', 'monospace', etc.

Color Format Support

Accepts multiple color formats:

  • Hex colors: '#ff0000', '#f00'
  • RGB/RGBA: 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 0.5)'
  • Named colors: 'red', 'blue', 'transparent'
  • React Native color formats

Performance Considerations

  • Image generation is synchronous on the native thread
  • Large text or high font sizes may impact performance
  • Consider caching generated images for repeated use
  • Clean up temporary image files when no longer needed

Error Scenarios

  • UnavailabilityError: Function not available on current platform (web)
  • Font not found: Falls back to system default font
  • Invalid color: May fall back to default black color
  • Memory issues: Large images may cause memory warnings

docs

font-loading.md

font-utils.md

index.md

react-hooks.md

server-side.md

tile.json