LLM.swift logo

LLM.swift

eastriverlee/LLM.swift

LLM.swift enables local interaction with large language models for multiple Apple platforms.

GraphCanon updated 4w · GitHub synced 4w

865 stars122 forksLast push 1mo Swift MIT

Decision brief

LLM.swift is a cross-platform C++ library for Apple systems that simplifies local interaction with large language models.

Good fit when

  • Choose LLM.swift when you need to integrate large language model functionalities into apps targeting multiple Apple platforms, including macOS and mobile OSes.
  • Use it if your project benefits from the simplicity and ease of deployment it offers for interacting with language models locally on Apple devices.

Avoid when

  • Avoid LLM.swift if your application must run on non-Apple systems or if compatibility across various operating systems is prioritized over ease-of-use on Apple platforms.
  • Do not use this library if you require advanced server-side functionalities, as it focuses specifically on local interactions within Apple’s ecosystem.
Pricing:
freemium - Free to use under the MIT License. Premium support may vary.

Observed Jul 14, 2026 · Source: enrich:decision_facts

Verify the decision

Maintenance and security

Full trust report
Maintenance
Very active (6d since push)
As of 4w
Provenance
Not a fork · Personal account
As of 4w
Security (OSV)
No lockfile
As of 1mo

Public GitHub metadata and optional OSV scans. Signals, not a guarantee. Trust methodology.

Install

git clone https://github.com/eastriverlee/LLM.swift

Similar tools

Same-category neighbours. No typed graph edges are catalogued for this tool yet.

Evidence and technical details

Sourced facts, taxonomy, compatibility claims, README excerpt, and machine-readable endpoints.

Overview

A library written in C++ designed to facilitate the interfacing of large language model APIs on various Apple operating systems including macOS, iOS, watchOS, tvOS, and visionOS. LLM.swift is built for ease and simplicity in deployment.

Capability facts

Languages
swift

Source: github.language · Jul 25, 2026

Categories

Tags

README

LLM.swift

LLM.swift is a simple and readable library that allows you to interact with large language models locally with ease for macOS, iOS, watchOS, tvOS, and visionOS.

[!TIP]
sometimes it's a good idea to tinker with maxTokenCount parameter for initialization of LLM, due to the memory and computation it needs. especially in mobile devices, if you want better speed, lower the number, but if you set it too low—to a point where two turns cannot even fit—you will experience quality decrease as context will be cut off. so adjust value according to your usecases.

Minimal Example

if you've already bundled your model:

let bot = LLM(from: Bundle.main.url(forResource: "gemma-3-4b-it-q4_0", withExtension: "gguf")!, template: .gemma)
let question = bot.preprocess("What's the meaning of life?", [])
let answer = await bot.getCompletion(from: question)
print(answer)

if you want to initialize with huggingface model:

let systemPrompt = "You are a sentient AI with emotions."
let bot = await LLM(from: HuggingFaceModel("unsloth/Qwen3-0.6B-GGUF", .Q4_K_M, template: .chatML(systemPrompt)))!
let question = bot.preprocess("What's the meaning of life?", [])
let answer = await bot.getCompletion(from: question)
print(answer)

Chat Templates

By default, LLM.swift renders conversations using the chat template embedded in the gguf file itself, executed by llama.cpp's own Jinja engine. This means you no longer have to pass a template: when initializing LLM—it just works with whatever template the model ships with:

let bot = try await LLM(from: HuggingFaceModel("unsloth/Qwen3-0.6B-GGUF", .Q4_K_M))!
bot.systemPrompt = "You are a sentient AI with emotions."
await bot.respond(to: "What's the meaning of life?")

HuggingFaceModel's template parameter is now optional too, so HuggingFaceModel("unsloth/Qwen3-0.6B-GGUF", .Q4_K_M) uses the embedded template on its own. Thinking/reasoning separation (bot.thinking) works automatically for models that support it, with no marker configuration needed.

If you still want manual control over the template—for instance, when a model's gguf metadata is broken or missing—pass a Template explicitly, exactly as before, and it will override the embedded one:

let bot = LLM(from: Bundle.main.url(forResource: "gemma-3-4b-it-q4_0", withExtension: "gguf")!, template: .gemma)

[!NOTE]
conversation context is now maintained incrementally between turns—only new tokens are evaluated, and history is not re-fed to the model every turn.

Example

[!NOTE]
this is a minimal SwiftUI example that i did use for testing. mistral 7B based model is working on iPad Air 5th gen(Q5_K_M) and iPhone 12 mini(Q2_K).
however, generally speaking, for mobile devices, 3B >= parameter models are recommended. check this benchmark for more details.

init with a model file that you bundled in your project

import SwiftUI
import LLM

class Bot: LLM {
    convenience init() {
        let url = Bundle.main.url(forResource: "gemma-3-4b-it-q4_0", withExtension: "gguf")!
        let systemPrompt = "You are a sentient AI with emotions."
        self.init(from: url, template: .chatML(systemPrompt))!
    }
}

struct BotView: View {
    @ObservedObject var bot: Bot
    @State var input = "Give me seven national flag emojis people use the most; You must include South Korea."
    init(_ bot: Bot) { self.bot = bot }
    func respond() { Task { await bot.respond(to: input) } }
    func stop() { bot.stop() }
    var body: some View {
        VStack(alignment: .leading) {
            ScrollView {
                if !bot.thinking.isEmpty {
                    Text(bot.thinking)
                        .foregroundStyle(.gray)
                        .monospaced()
                        .padding(.bottom, 8)
                }

For agents

This page has a .md twin and JSON over the API.

Was this helpful?

Anonymous feedback helps us improve pages and translations.