# Using a Hugging Face model in an iOS app > Three ways to put a Hugging Face model in an iOS app: a ready Core ML package, a conversion with coremltools, or MLX Swift for language models. Xcode steps, size, licenses and the privacy angle, with Swift that type-checks. - Canonical page: https://obelisk.club/blog/hugging-face-models-in-ios-apps-core-ml - Author: Peter Zhang - Published: 2026-11-02 - Tags: core-ml, hugging-face, ios, swift, on-device, indie If a Core ML version of the model already exists on Hugging Face, download the `.mlpackage`, drag it into your Xcode project, and call the Swift class Xcode writes for it. If the model only exists as PyTorch weights, convert it with `coremltools` (`ct.convert`, then `save("model.mlpackage")`). If it is a language model, look at MLX Swift instead. Before any of that, read the license on the model card, because "downloadable" does not mean "free to ship". I downloaded a real Core ML model from Hugging Face for this guide, generated its Swift class with Apple's `coremlcompiler`, and compiled the Swift below with Xcode 27.1 (Swift 6.4) against the iOS 18 simulator SDK. The coremltools step comes from Apple's documentation and I did not run it. ## Which route for which model | Starting point | Route | What you ship | |---|---|---| | Repo tagged `coreml` with an `.mlpackage` (for example the `apple/` organization) | Download it and add it to Xcode | A compiled Core ML model in the app, or downloaded later | | Model published as PyTorch or TensorFlow weights | Convert with coremltools, then add to Xcode | A model package you produced; check the license allows it | | Chat or text-generation language model | MLX Swift (`mlx-swift-lm`) with a model from the `mlx-community` org | A Swift package plus a model downloaded at run time | ## Route 1: a ready Core ML package Hugging Face model cards carry metadata tags such as `coreml`, and Apple publishes Core ML versions of several vision models under its own `apple/` organization. I picked [apple/coreml-FastViT-T8](https://huggingface.co/apple/coreml-FastViT-T8), an image classifier trained on ImageNet-1k. Its card says it has 4.0 million parameters, takes a 256 x 256 image, and the Float16 package is 7.8 MB. The card's own instructions download it with the Hugging Face command line tool: ```bash huggingface-cli download \ --local-dir models --local-dir-use-symlinks False \ apple/coreml-FastViT-T8 ``` I fetched the same files with the `huggingface_hub` Python library instead; the result is the same folder, `FastViTT8F16.mlpackage`, plus a `README.md` and a `LICENSE` file. Check what the repo actually contains before you plan around it: some `apple/` repos hold older `.mlmodel` files instead of packages, for example `apple/coreml-resnet-50`. ### Add it to Xcode Apple's sample describes the steps: drag the model into the project navigator, and open it in Xcode to see the model type and its expected inputs and outputs. Xcode then writes a Swift interface for the model, its input and its output, and compiles the model into a form optimized for the device, which is what ships in the app bundle. You can see exactly what Xcode writes without opening Xcode. This command, run on the downloaded package, produced one Swift file: ```bash xcrun coremlcompiler generate FastViTT8F16.mlpackage gen --language Swift ``` The file defines three classes for this model: - `FastViTT8F16Input`, with an `image` property (a `CVPixelBuffer`, 256 by 256) and convenience initializers that take a `CGImage` or a file URL - `FastViTT8F16Output`, with `classLabel` (a `String`) and `classLabel_probs` (a `[String: Double]`) - `FastViTT8F16`, with `load()` and `prediction(input:)` in synchronous, completion handler and `async` forms This code uses that generated class. I compiled it together with the generated file using the command from the next section, and it type-checks: ```swift import CoreML import CoreGraphics func classify(_ image: CGImage) async throws -> (label: String, probability: Double) { let model = try await FastViTT8F16.load() let input = try FastViTT8F16Input(imageWith: image) let output = try await model.prediction(input: input) return (output.classLabel, output.classLabel_probs[output.classLabel] ?? 0) } ``` I compiled it but did not run a prediction on a photo, so I have no accuracy result to report. The model card lists a 0.9 percent drop in accuracy against the original PyTorch model for this Float16 version, and inference times it measured (0.79 ms on an iPhone 12 Pro Max, 0.62 ms on an M3 Max, mostly on the Neural Engine). Those are the card's numbers, not mine. ### Or load it with MLModel Apple's docs say that in most cases you can use the wrapper class without touching `MLModel`, but an app that downloads and compiles a model on the user's device must use the `MLModel` class directly. In that case you call `MLModel.compileModel(at:)` on the downloaded file and open the compiled copy. This version type-checks for an iOS 18 target: ```swift import CoreML import Foundation func loadModel(packageURL: URL) async throws -> MLModel { let compiledURL = try await MLModel.compileModel(at: packageURL) let configuration = MLModelConfiguration() configuration.computeUnits = .all return try await MLModel.load(contentsOf: compiledURL, configuration: configuration) } ``` The check, run from the Terminal: ```bash xcrun swiftc -typecheck -parse-as-library \ -target arm64-apple-ios18.0-simulator \ -sdk $(xcrun --show-sdk-path --sdk iphonesimulator) load.swift ``` I also built a small macOS command line tool around the same function and ran it on the downloaded package. It printed the model's description: `input image 4 256x256`, `output classLabel 3` and `output classLabel_probs 6` (those numbers are the raw values of Core ML's feature type enum, not sizes). `computeUnits = .all` lets the system choose the processing unit, including the Neural Engine if the device has one; Apple's docs say `.cpuOnly` is for apps that may run in the background or do other GPU-heavy work. Apple's guide on downloading models also says Core ML puts compiled models in a temporary location, so save the compiled model somewhere permanent, such as Application Support, if you want to reuse it. It also warns to think about iCloud Backup size for large models. ## Route 2: convert with coremltools When a model has no Core ML version, Apple's [coremltools documentation](https://apple.github.io/coremltools/docs-guides/source/convert-pytorch-workflow.html) describes two steps: capture the PyTorch model graph with `torch.jit.trace` (the documented stable path) or `torch.export`, then convert it. This is the docs' own flow, shown here without my having run it: ```python import torch import torchvision import coremltools as ct # Load a pre-trained model and put it in evaluation mode. torch_model = torchvision.models.mobilenet_v2(pretrained=True) torch_model.eval() # Trace it with an example input. example_input = torch.rand(1, 3, 224, 224) traced_model = torch.jit.trace(torch_model, example_input) # Convert and save as a model package. model = ct.convert( traced_model, inputs=[ct.TensorType(shape=example_input.shape)], ) model.save("newmodel.mlpackage") ``` Details from the docs: since Core ML Tools 7.0, `convert()` produces an ML program by default, and ML programs must be saved as an `.mlpackage`, not an `.mlmodel`. The weights and intermediate values are Float16 by default, and you can ask for Float32 with `compute_precision=ct.precision.FLOAT32` when Float16 is not precise enough. For image models, the docs point to `ImageType` inputs instead of the `TensorType` used above (see their Image Input and Output page). They also say the newer `torch.export` path covered roughly 70 percent of PyTorch operations as of Core ML Tools 8.0, so a model can fail to convert; keep test inputs from the original model and compare outputs before and after. ## Route 3: language models with MLX Swift Core ML is the right default for vision, audio and classic models. For chat-style language models, The `ml-explore` organization publishes [mlx-swift-lm](https://github.com/ml-explore/mlx-swift-lm), a Swift package for building tools and apps with large language models and vision language models. Its README shows how to add it to `Package.swift` and which products to link, and it can load models from the Hugging Face Hub. The [MLX guide](/blog/run-hugging-face-models-mac-mlx) covers trying the same models on your Mac first, and the `mlx-swift-examples` repo has an app that runs on both iOS and macOS and downloads a language model. I have not built an app with it for this guide, so I give no memory or speed figures for iPhone. ## Size and memory on the device I could find no memory table for iPhones in Apple's or Hugging Face's docs, so I will not invent one. What the sources do say: - Bundling a model is the simplest way to start, but advanced models take significant storage. Apple suggests lower precision weights (from 32 down to 16 bits, or lower, 1 to 8 bits) through the coremltools utilities. - If you still need a smaller download, Apple describes downloading the model after install and compiling it on the device, for example when users need only some of the models your app supports. - The coremltools docs have separate sections on palettization, linear quantization and pruning for compressing weights. - The model card for FastViT lists two variants, T8 at 7.8 MB and MA36 at 84 MB. Pick the smallest one that meets your quality bar, and test on the oldest device you support. ## Check the license before you ship Hugging Face says a license is set in the model card's metadata and asks you to respect it. Cards differ, and this matters for apps you sell: - `apple/coreml-resnet-50` is tagged `mit`. - `apple/coreml-FastViT-T8` is tagged `other`, with `license_name: apple-ascl` and a `LICENSE` file in the repo. Its card says to observe the original license. "Other" means you must read the file; I did not interpret it for you. - A converted model is a derived copy, so the original model's terms follow it, and so do the terms of its training data, if the card lists any. Write down the license, the model's repo URL and the commit you downloaded, and keep them with your release notes. ## What this means for App Review and privacy Apple's App Privacy Details page defines "collect" as transmitting data off the device in a way that lets you or your partners access it for longer than needed to service the request in real time. It also says data processed only on the device is not "collected" and does not need to be disclosed in your App Store Connect answers. So an on-device model that works on a photo and never sends it anywhere can keep that photo out of your data collection answers. Three cautions: - The rule covers data that stays on the device. If your app also sends the photo, the result or any usage data to a server or a third-party SDK, answer for that. - Downloading a model at run time is a network request. It sends the request itself, such as an IP address, so look at how you host it and what your host keeps. - A privacy policy URL is still required for every app, even one that collects nothing. See [Does my iOS app need a privacy policy?](/blog/ios-app-privacy-policy-requirements) for the details, and describe in plain words what the model does with the user's input. ## Clean up All files for this guide lived in a scratch folder: the model (7.8 MB), the generated Swift file and a compiled copy. The whole folder was 16 MB, and nothing was added to a project. ## Sources All read on 2 November 2026. - [apple/coreml-FastViT-T8](https://huggingface.co/apple/coreml-FastViT-T8), the package, its card, license and download instructions - [apple/coreml-resnet-50](https://huggingface.co/apple/coreml-resnet-50), the license tag and the `.mlmodel` files - [Integrating a Core ML model into your app](https://developer.apple.com/documentation/coreml/integrating-a-core-ml-model-into-your-app), adding a model and the wrapper Xcode writes - [MLModel](https://developer.apple.com/documentation/coreml/mlmodel), the wrapper class versus the `MLModel` interface - [Downloading and compiling a model on the user's device](https://developer.apple.com/documentation/coreml/downloading-and-compiling-a-model-on-the-user-s-device), `compileModel(at:)` and saving the compiled copy - [Reducing the size of your Core ML app](https://developer.apple.com/documentation/coreml/reducing-the-size-of-your-core-ml-app), lower precision weights and downloading models - [MLComputeUnits](https://developer.apple.com/documentation/coreml/mlcomputeunits), processing unit choices - [PyTorch Conversion Workflow](https://apple.github.io/coremltools/docs-guides/source/convert-pytorch-workflow.html), tracing, `ct.convert` and `save` - [Convert Models to ML Programs](https://apple.github.io/coremltools/docs-guides/source/convert-to-ml-program.html), the default model type, precision and the `.mlpackage` format - [Licenses on the Hugging Face Hub](https://huggingface.co/docs/hub/repositories-licenses) and [Model Cards](https://huggingface.co/docs/hub/model-cards), license metadata - [mlx-swift-lm](https://github.com/ml-explore/mlx-swift-lm) and [mlx-swift-examples](https://github.com/ml-explore/mlx-swift-examples), language models in Swift - [App Privacy Details](https://developer.apple.com/app-store/app-privacy-details/), the definition of "collect" and on-device processing