StringLane

    Type to search titles, sections and body text across all 58 pages.

    How-To

    Translate App Strings with a Local LLM (Ollama, LM Studio)

    Translate your app's localization files with Ollama, LM Studio or Jan on your own machine. Base URLs, setup, model choice, and the speed to expect.

    Last updated

    StringLane's Local LLM (OpenAI-compatible) provider lets you translate without sending data to any cloud. It works with any inference runner that exposes an OpenAI-compatible HTTP API: Ollama, LM Studio, Jan, llama.cpp, vLLM. Translations are written to your locale files and validated like any other edit, so a local model that drops a placeholder or a plural category is flagged on that cell.

    Why local#

    • No API key, no per-token billing.
    • No network egress. Your strings stay on the machine.
    • No rate limits beyond your hardware.
    • Smaller models (Llama 3.2, Qwen 2.5, Mistral 7B) are good enough for translation tasks when paired with StringLane's locale-aware prompts.

    Step 1: Run a local model server#

    Pick whichever runner you already have:

    RunnerDefault base URLHow to install
    Ollamahttp://localhost:11434/v1brew install ollama && ollama pull llama3.2
    LM Studiohttp://localhost:1234/v1Download the desktop app, load a model, click "Start Server"
    Janhttp://localhost:1337/v1Download the desktop app, enable the "Local API Server"
    llama.cppvaries./llama-server -m model.gguf --port 8080

    Start the server, pull/load a model, and confirm you can curl the /v1/models endpoint.

    Step 2: Configure StringLane#

    Open Settings → App → AI Providers (or run "Open Settings" from the Command Palette).

    1. Provider: pick Local LLM (OpenAI-compatible).
    2. Base URL: enter your runner's URL. Default is http://localhost:11434/v1 (Ollama). Adjust per the table above.
    3. Model: type the exact model name your runner has loaded (e.g. llama3.2, qwen2.5:14b, mistral).
    4. No API key field appears: local runners typically don't authenticate.
    Settings → App → AI Providers with the Local LLM (OpenAI-compatible) provider selected, a model name, the Local Server Base URL pointing at http://localhost:11434/v1, and Concurrent requests set to 2 (default) with a note that most local servers handle one request at a time

    Save and close Settings.

    Step 3: Translate#

    Use the same flows you would with a cloud provider:

    • Per-cell ✨ button on a Missing or Same row.
    • ⌘T: translate the active key into every non-base locale.
    • ⌘⇧T: translate (or re-translate) only the focused locale's field, leaving the key's other locales untouched.
    • Translate all missing with AI from the Command Palette: sweeps every gap across every locale.
    • Fix all with AI in the Issues Panel: repairs ICU and placeholder errors in place.

    StringLane's prompts already include CLDR plural rules, locale formality / honorifics, format-specific placeholder dialects, and a glossary of recurring terms. Those are sent regardless of provider, so a local model gets the same context a cloud model does.

    What to expect#

    • Latency. A local 7B model on a Mac M-series will produce a translation in 1-3 seconds per key. A bulk run sends as many requests at once as Settings → App → AI Providers → Concurrent requests allows (default 2). Most local servers answer one request at a time, so raising it rarely helps unless your runner supports concurrent inference, as LM Studio and vLLM do.
    • Quality. Larger models (14B+) match cloud quality on common locale pairs. Smaller models (3B-7B) are adequate for short UI strings; quality drops on complex ICU plurals or rare locale pairs.
    • Memory. Plan for the runner to hold the model in VRAM/unified memory while StringLane is open. Quit the runner when you're done if you need the RAM back.

    Troubleshooting#

    • "Could not reach the model server" error: confirm the runner is up (curl http://localhost:11434/v1/models) and the URL in Settings exactly matches.
    • Translation comes back as a code block or refusal: the model is misinterpreting the system prompt. Try a different model; instruction-tuned *-instruct variants behave best.
    • Empty translations: the runner returned non-JSON. StringLane's parser logs a TranslationParseError and skips that key. Check the runner's console for the raw response.
    The StringLane app showing the key home.welcomeBack, used in three places in Swift files, with four locale cards: English, German and Japanese in place and French flagged PARAM.

    See every locale side by side

    The desktop app flags what is missing or broken on the cell, and saves to your files.

    Download for macOS

    14-day trial, no email