Skip to content

Repository files navigation

Locanara

Locanara

On-Device AI Framework for iOS and Android

License


Overview

Locanara is an on-device AI framework inspired by LangChain, purpose-built for mobile. Build, compose, and extend AI features using platform-native models — all processing happens locally on the device.

No cloud. No data leaves. Privacy by design.

Documentation: locanara.hyo.dev | Blog: LangChain for Mobile, Entirely On-Device — Meet Locanara


Supported Platforms

iOS / macOS

Engine Description Requirements
Apple Intelligence OS-level Foundation Models iOS 18.1+ / macOS 15.1+ (iOS 26+ / macOS 26+ recommended), Apple Silicon, 7GB+ free space
llama.cpp GGUF models with Metal GPU acceleration iOS 17+ / macOS 14+, Apple Silicon
CoreML Neural Engine accelerated inference iOS 17+ / macOS 14+, Apple Silicon
MLX Apple Silicon optimized inference macOS 14+, Apple Silicon

Android

Engine Description Requirements
Gemini Nano ML Kit GenAI (Prompt API) Android 14+ (API 34+)
ExecuTorch Meta's on-device inference runtime Android 12+ (API 31+)

Locanara automatically detects device capabilities and routes inference to the best available engine.


Why Locanara?

Most on-device AI SDKs give you raw model access. Locanara gives you a framework — composable chains, memory management, guardrails, and a pipeline DSL — so you can build production AI features, not just call a model.

Three Levels of API

  1. Simple — Call a model extension for a common task.
  2. Chain — Configure and run a built-in chain directly.
  3. Custom — Implement Chain for app-specific behavior.

Swift

import Foundation
import Locanara

let model = LocanaraDefaults.model
let article = "On-device AI keeps private data on the device."

// 1. Simple
let summary = try await model.summarize(article, bulletCount: 3)

// 2. Chain
let chain = SummarizeChain(model: model, bulletCount: 3)
let configured = try await chain.run(article)

// 3. Custom
struct TrimChain: Chain {
    let name = "TrimChain"

    func invoke(_ input: ChainInput) async throws -> ChainOutput {
        let text = input.text.trimmingCharacters(in: .whitespacesAndNewlines)
        return ChainOutput(value: text, text: text, metadata: input.metadata)
    }
}

Kotlin

import com.locanara.builtin.SummarizeChain
import com.locanara.composable.Chain
import com.locanara.core.ChainInput
import com.locanara.core.ChainOutput
import com.locanara.core.LocanaraDefaults
import com.locanara.dsl.summarize

suspend fun threeLevelsExample() {
    val model = LocanaraDefaults.model
    val article = "On-device AI keeps private data on the device."

    // 1. Simple
    val summary = model.summarize(article, bulletCount = 3)

    // 2. Chain
    val chain = SummarizeChain(model = model, bulletCount = 3)
    val configured = chain.run(article)

    // 3. Custom
    class TrimChain : Chain {
        override val name = "TrimChain"

        override suspend fun invoke(input: ChainInput): ChainOutput {
            val text = input.text.trim()
            return ChainOutput(value = text, text = text, metadata = input.metadata)
        }
    }
}

Architecture

┌─────────────────────────────────────────────┐
│  Runtime Layer                              │
│  Agent · Session · ChainExecutor            │
├─────────────────────────────────────────────┤
│  Built-in Chains                            │
│  Summarize · Classify · Chat · Translate ·  │
│  Extract · Rewrite · Proofread              │
├─────────────────────────────────────────────┤
│  Composable Layer                           │
│  Chain · Tool · Memory · Guardrail          │
├─────────────────────────────────────────────┤
│  Core Layer                                 │
│  LocanaraModel · PromptTemplate ·           │
│  OutputParser · Schema                      │
├─────────────────────────────────────────────┤
│  DSL Layer                                  │
│  Pipeline · PipelineStep · ModelExtensions  │
├─────────────────────────────────────────────┤
│  Platform Layer                             │
│  FoundationLanguageModel · PromptApiModel   │
├─────────────────────────────────────────────┤
│  Engine Layer                               │
│  InferenceRouter · LlamaCppEngine ·         │
│  ExecuTorchEngine · DeviceCapabilityDetector│
├─────────────────────────────────────────────┤
│  ModelManager Layer                         │
│  ModelManager · ModelDownloader ·           │
│  ModelRegistry · ModelStorage               │
├─────────────────────────────────────────────┤
│  RAG Layer                                  │
│  VectorStore · DocumentChunker ·            │
│  EmbeddingEngine · RAGQueryEngine           │
├─────────────────────────────────────────────┤
│  Personalization Layer                      │
│  PersonalizationManager · FeedbackCollector │
│  PreferenceAnalyzer · PromptOptimizer       │
└─────────────────────────────────────────────┘

Installation

iOS (Swift Package Manager)

https://github.com/hyodotdev/locanara

Android (Gradle)

implementation("com.locanara:locanara:1.1.2")

Key Features

Framework Layer

  • Chain — Composable unit of AI logic with typed input/output
  • Pipeline DSL — Compose chains while tracking the last step's result type
  • Memory — BufferMemory (last N turns) and SummaryMemory (compressed history)
  • Guardrail — Input/output validation and content filtering
  • Tool — External capability integration for agents

Built-in Chains

7 ready-to-use chains, each returning typed results:

Chain Result Type Description
SummarizeChain SummarizeResult Text summarization
ClassifyChain ClassifyResult Text classification
ExtractChain ExtractResult Entity extraction
ChatChain ChatResult Conversational AI with memory
TranslateChain TranslateResult Language translation
RewriteChain RewriteResult Text rewriting by style
ProofreadChain ProofreadResult Grammar correction

Engine System

  • InferenceEngine — Unified protocol for all inference backends
  • InferenceRouter — Automatic engine selection based on device capabilities
  • DeviceCapabilityDetector — Hardware detection (NPU, memory, chipset)
  • MemoryManager — Intelligent memory allocation for model loading

Model Management

  • ModelManager — Download, load, and manage on-device models
  • ModelRegistry — Available model catalog with metadata
  • ModelDownloader — Background download with progress tracking
  • ModelStorage — Local storage and cache management

RAG (Retrieval-Augmented Generation)

  • VectorStore — Local vector storage for embeddings
  • DocumentChunker — Text splitting with configurable strategies
  • EmbeddingEngine — On-device embedding generation
  • RAGQueryEngine — Similarity search and context retrieval

Personalization

  • FeedbackCollector — Collect user feedback on AI outputs
  • PreferenceAnalyzer — Learn user preferences over time
  • PromptOptimizer — Adapt prompts based on user behavior

Runtime Layer

  • ChainExecutor — Instrumented execution with retry and history
  • Session — Stateful conversation management
  • Agent — ReAct-lite autonomous agent with tools

Pipeline DSL

Compose multiple AI steps into one workflow. Each step passes its text and metadata to the next step, and the last step determines the pipeline's compile-time return type. The builders do not prove that every adjacent step is semantically compatible.

Manual Composition (all platforms)

Swift

import Locanara

let model = FoundationLanguageModel()

// Step 1: fix typos
let proofread = try await model.proofread(
    "Ths is a tset of on-devce AI."
)

// Step 2: translate the corrected text
let translated = try await model.translate(
    proofread.correctedText, to: "ko"
)
print(translated.translatedText)

Kotlin

import com.locanara.dsl.*
import com.locanara.platform.PromptApiModel

suspend fun example(context: Context) {
    val model = PromptApiModel(context)

    // Step 1: fix typos
    val proofread = model.proofread(
        "Ths is a tset of on-devce AI."
    )

    // Step 2: translate the corrected text
    val translated = model.translate(
        proofread.correctedText, to = "ko"
    )
    println(translated.translatedText)
}

Declarative Pipeline Builder (Swift)

Swift's @PipelineBuilder tracks the last step's result type. Assigning the result to a different type is a compile error, while adjacent steps still exchange ChainOutput.text and metadata at runtime.

import Locanara

let model = FoundationLanguageModel()

// Two-step: proofread → translate
// Return type is TranslateResult — tracked from the final step
let result = try await model.pipeline {
    Proofread()
    Translate(to: "ko")
}.run("Ths is a tset sentece about on-devce AI.")

print(result.translatedText)   // "이것은 온디바이스 AI에 관한 테스트 문장입니다."
print(result.targetLanguage)   // "ko"

// Three-step: summarize → proofread → translate
let threeStep = try await model.pipeline {
    Summarize(bulletCount: 3)
    Proofread()
    Translate(to: "ja")
}.run(longArticle)
// Returns TranslateResult (last step determines the type)

Kotlin Pipeline DSL

import com.locanara.dsl.*
import com.locanara.platform.PromptApiModel

suspend fun pipelineExample(context: Context) {
    val model = PromptApiModel(context)

    // Fluent pipeline API
    val result = model.pipeline()
        .proofread()
        .translate(to = "ko")
        .run("Ths is a tset sentece about on-devce AI.")

    // result is TranslateResult (the final step determines the type)
    println(result.translatedText)

    // Three-step pipeline
    val threeStep = model.pipeline()
        .summarize(bulletCount = 3)
        .proofread()
        .translate(to = "ja")
        .run(longArticle)
}

Available Pipeline Steps

Step Swift Kotlin Output
Summarize Summarize(bulletCount:) .summarize(bulletCount:) SummarizeResult
Classify Classify(categories:) .classify(categories:) ClassifyResult
Translate Translate(to:) .translate(to:) TranslateResult
Proofread Proofread() .proofread() ProofreadResult
Rewrite Rewrite(style:) .rewrite(style:) RewriteResult
Extract Extract(entityTypes:) .extract(entityTypes:) ExtractResult

Web and wrappers: The Web SDK, Expo, React Native, and Flutter APIs do not expose the native Pipeline builder. Compose their feature calls explicitly and use streaming methods such as summarizeStreaming(), translateStreaming(), and rewriteStreaming() where supported.

Full tutorial: locanara.hyo.dev/docs/tutorials/pipeline


Packages

Libraries


Requirements

iOS / macOS

  • Minimum: iOS 17+ / macOS 14+ (llama.cpp, CoreML engines)
  • Apple Intelligence: iOS 18.1+ / macOS 15.1+ (iOS 26+ / macOS 26+ recommended)
    • Requires Apple Silicon (A17 Pro+ for iPhone, M1+ for Mac)
    • Requires 7GB+ free storage space
  • Apple Silicon device required for all engines

Android

  • Minimum: Android 12+ (API 31+) for ExecuTorch engine
  • Full: Android 14+ (API 34+) for Gemini Nano engine
  • Device with NPU support recommended

License

AGPL-3.0 License — see LICENSE for details.


Built with conviction that AI should run where your data lives — on your device.

About

On-device AI framework inspired by LangChain, purpose-built for mobile. Build, compose, and extend AI features using platform-native models — all processing happens locally on the device.

Topics

Resources

Contributing

Stars

9 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages