Getting Started

Quick Start

Run your first OCR detection with RustO! across all supported platforms in under 5 minutes.

Get up and running with RustO! across different languages with these concise, copy-pasteable examples.

Sample Document Image

Assume we have an input receipt image receipt.jpg:

┌────────────────────────────────────────┐
│             COFFEE SHOP                │
│ 2026-08-20                     12:30   │
│                                        │
│ Item                  Qty       Price  │
│ ────────────────────────────────────── │
│ Espresso Double         1       $4.50  │
│ Croissant               2       $7.00  │
│ Flat White              1       $5.00  │
│ ────────────────────────────────────── │
│ Total                          $16.50  │
└────────────────────────────────────────┘

1. Rust

use rusto::{
    DetectTextResult, ImageSource, InitializeConfig, OcrRunOptions,
    OutputGranularity, RustO,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Initialize engine with PP-OCRv6 default preset
    let config = InitializeConfig::ppv6("models/det.rten", "models/rec.rten", "models/dict.txt");
    let mut ocr = RustO::initialize(config)?;

    // 2. Run structured line OCR
    let image = ImageSource::Path("receipt.jpg".into());
    let mut options = OcrRunOptions::default();
    options.output = OutputGranularity::Lines;

    let result = ocr.detect_text(&image, &options)?;

    match result {
        DetectTextResult::Structured(lines) => {
            println!("--- Structured Line Results ({} lines) ---", lines.len());
            for line in lines {
                println!(
                    "[{:5.1}, {:5.1}, {:5.1}, {:5.1}] (Score: {:.2}) {}",
                    line.frame.left, line.frame.top, line.frame.width, line.frame.height,
                    line.score, line.text
                );
            }
        }
        DetectTextResult::Spatial(text) => println!("{text}"),
    }

    // 3. Run spatial layout reconstruction OCR
    options.output = OutputGranularity::Spatial;
    options.line_y_threshold = Some(0.5);
    options.word_x_threshold = Some(0.4);

    if let DetectTextResult::Spatial(spatial_text) = ocr.detect_text(&image, &options)? {
        println!("\n--- Reconstructed Spatial Layout ---\n{spatial_text}");
    }

    Ok(())
}

2. Node.js (TypeScript / JavaScript)

import { RustO } from '@rustors/node';

const config = {
  detection: { model_path: 'models/det.rten' },
  recognition: { model_path: 'models/rec.rten', dict_path: 'models/dict.txt' }
};

const engine = new RustO(JSON.stringify(config));

// Structured line recognition
const lines = engine.detectTextFile('receipt.jpg', JSON.stringify({}));
for (const line of lines) {
  console.log(`[${line.score.toFixed(2)}] ${line.text}`);
}

// Spatial layout reconstruction
const spatialText = engine.detectTextFileSpatial('receipt.jpg', JSON.stringify({}));
console.log(spatialText);

3. Python

from rusto import RustO, InitializeConfig, OcrRunOptions, ImageSource, OutputGranularity

# Initialize engine with PP-OCRv6 preset
config = InitializeConfig.ppv6("models/det.rten", "models/rec.rten", "models/dict.txt")
engine = RustO.initialize(config)

# Structured line recognition
options = OcrRunOptions(output=OutputGranularity.LINES)
result = engine.detect_text(ImageSource.PATH("receipt.jpg"), options)
if result.is_STRUCTURED():
    for line in result.results:
        print(f"[{line.score:.2f}] {line.text}")

# Spatial layout reconstruction
spatial_options = OcrRunOptions(output=OutputGranularity.SPATIAL)
spatial_result = engine.detect_text(ImageSource.PATH("receipt.jpg"), spatial_options)
if spatial_result.is_SPATIAL():
    print(spatial_result.text)

4. Golang

package main

import (
    "fmt"
    "log"

    "github.com/byrizki/rusto-rs/packages/go"
)

func main() {
    config := `{"detection":{"model_path":"models/det.rten"},"recognition":{"model_path":"models/rec.rten","dict_path":"models/dict.txt"}}`
    engine, err := rusto.New(config)
    if err != nil {
        log.Fatalf("Init failed: %v", err)
    }
    defer engine.Close()

    lines, err := engine.DetectTextFile("receipt.jpg", "{}")
    if err != nil {
        log.Fatalf("OCR failed: %v", err)
    }

    for _, line := range lines {
        fmt.Printf("[%.2f] %s\n", line.Score, line.Text)
    }
}

5. Java / Kotlin

import com.byrizki.rusto.RustO;
import com.byrizki.rusto.TextResult;
import java.util.List;

public class App {
    public static void main(String[] args) {
        String config = "{\"detection\":{\"model_path\":\"models/det.rten\"},\"recognition\":{\"model_path\":\"models/rec.rten\",\"dict_path\":\"models/dict.txt\"}}";
        try (RustO engine = RustO.initialize(config)) {
            List<TextResult> lines = engine.detectTextFile("receipt.jpg");
            for (TextResult line : lines) {
                System.out.printf("[%.2f] %s%n", line.getScore(), line.getText());
            }
        }
    }
}

6. Flutter & Dart

import 'package:rusto/rusto.dart';

void main() {
  final engine = RustO.initialize('''
  {
    "detection": { "model_path": "models/det.rten" },
    "recognition": { "model_path": "models/rec.rten", "dict_path": "models/dict.txt" }
  }
  ''');

  final results = engine.detectTextFile('receipt.jpg');
  for (final line in results) {
    print('[${line.score.toStringAsFixed(2)}] ${line.text}');
  }
  engine.close();
}

7. .NET / C#

using System;
using RustODotnet;

// 1. Initialize engine (loads bundled PP-OCRv6 models automatically)
using var ocr = RustO.Initialize();

// 2. Structured line detection
var imageSource = new UriImageSource("receipt.jpg");
var options = new OcrRunOptions { Output = OutputGranularity.Lines };

var result = ocr.DetectText(imageSource, options);
if (result is StructuredDetectTextResult structured)
{
    foreach (var item in structured.Items)
    {
        Console.WriteLine($"[{item.Frame.Left:F0}, {item.Frame.Top:F0}] ({item.Score:P0}) {item.Text}");
    }
}

// 3. Spatial text reconstruction
var spatialOptions = new OcrRunOptions { Output = OutputGranularity.Spatial };
var spatialResult = ocr.DetectText(imageSource, spatialOptions);
if (spatialResult is SpatialDetectTextResult spatial)
{
    Console.WriteLine("\n--- Spatial Layout ---");
    Console.WriteLine(spatial.Text);
}

8. React Native

import React, { useEffect, useState } from 'react';
import { Button, SafeAreaView, ScrollView, Text } from 'react-native';
import { detectText, initialize, TextResult } from '@rustors/react-native';

export default function QuickScanApp() {
  const [lines, setLines] = useState<TextResult[]>([]);

  useEffect(() => {
    initialize();
  }, []);

  const handleScanStructured = async () => {
    const results = await detectText(
      { uri: 'file:///path/to/receipt.jpg' },
      { output: 'lines' }
    );
    setLines(results as TextResult[]);
  };

  return (
    <SafeAreaView style={{ flex: 1, padding: 16 }}>
      <Button title="Scan Lines" onPress={handleScanStructured} />
      <ScrollView style={{ marginTop: 16 }}>
        {lines.map((line, idx) => (
          <Text key={idx}>{line.text} ({Math.round(line.score * 100)}%)</Text>
        ))}
      </ScrollView>
    </SafeAreaView>
  );
}

9. iOS (Swift)

import Foundation
import RustO

func runQuickOcr() {
    do {
        let ocr = try RustO.initialize()
        let result = try ocr.detectText(.uri("receipt.jpg"), options: OcrRunOptions(output: .lines))
        if case .structured(let items) = result {
            for item in items {
                print("[\(item.frame.left), \(item.frame.top)] (\(item.score)) \(item.text)")
            }
        }
    } catch {
        print("OCR Error: \(error)")
    }
}

10. Android (Kotlin)

package com.example.ocr

import android.content.Context
import com.byrizki.rusto.*

fun processReceipt(context: Context, imageUri: String) {
    RustO.initialize(context).use { ocr ->
        val source = ImageSource.Uri(imageUri)
        val structured = ocr.detectText(source, OcrRunOptions(output = OutputGranularity.LINES))
        if (structured is DetectTextResult.Structured) {
            structured.items.forEach { line ->
                println("${line.text} (Score: ${line.score})")
            }
        }
    }
}

11. Command Line Interface (CLI)

# 1. Output structured JSON with bounding polygon vertices
rusto --det-model det.rten --rec-model rec.rten --dict dict.txt --format json receipt.jpg

# 2. Output formatted spatial text layout
rusto --det-model det.rten --rec-model rec.rten --dict dict.txt --format text-ordered receipt.jpg

# 3. Output tab-separated values (TSV)
rusto --det-model det.rten --rec-model rec.rten --dict dict.txt --format tsv receipt.jpg