Model or dataset
MacPaw/OpenAI avatar
MacPaw/OpenAI

MacPaw/OpenAI: a Swift package for the OpenAI API

Swift community driven package for OpenAI public API

2,944 stars518 forksSwiftMIT

At a glance

What is it?
MacPaw/OpenAI is a community-maintained Swift package that wraps the OpenAI public REST API for Swift Package Manager projects. It is a good fit for native Apple-platform apps, but the README expects you to proxy requests through your own backend rather than ship an API key in a client.
Who is it for?
Adopt MacPaw/OpenAI if you are building a Swift or Apple-platform app and want typed calls to the OpenAI REST API without writing your own models. Do not adopt it if you need a client-side app to hold the API key directly, since the README states production requests must be routed through your own backend.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What MacPaw/OpenAI solves for Swift developers

Calling the OpenAI REST API from Swift means writing Codable types for every request and response, handling streaming, and keeping all of that in sync as the API changes. MacPaw/OpenAI packages that work as a Swift library. The README describes it as a "Swift community-maintained implementation over OpenAI public API", and the repository is published under the MIT licence by MacPaw.

The intended audience is Swift developers, mostly on Apple platforms. The topics list includes spm and swiftpackagemanager, and the README's installation section covers only Swift Package Manager, so the project is aimed at Xcode projects and Swift server code rather than cross-language use. If you are writing Python or JavaScript, this package is not for you.

The README states the library implements its types and methods in close accordance with the REST API documentation on platform.openai.com. That is the design promise: the Swift surface tracks the HTTP API rather than inventing an abstraction on top of it.

How the client is structured and how requests flow

The entry point is an `OpenAI` class, described in the README as the entry point to the API. It is initialized with an API token, or with an `OpenAI.Configuration` value that also carries an organization identifier and a timeout interval. The README notes that `OpenAI.Configuration` accepts further values such as `host`, `basePath`, `port`, `scheme` and `customHeaders`, which is what lets the same client point at a non-OpenAI endpoint.

Methods are exposed through an `OpenAIProtocol`. The README shows a `responses` variable on that protocol for Responses API methods, and elsewhere uses calls such as `openAIClient.chats(query:)` and `openAIClient.images(query:)`. Each API area in the README follows the same shape: a query type goes in, a result comes back.

Three calling styles are documented. Swift Concurrency calls return async results and are cancelled by cancelling the enclosing task, which the README says cancels the underlying `URLSessionDataTask` automatically. Closure-based calls return a discardable `CancellableRequest` that you hold to cancel later. Combine calls return a publisher, and you cancel by discarding the subscription or calling `cancel()` on it.

The repository layout shows an `openapi.yaml` file and an `openapi-generator-config.yaml` at the top level, alongside a Makefile. The Makefile comments say generation requires a local fork of apple/swift-openapi-generator checked out as a sibling directory named `swift-openapi-generator`. So the Swift types are generated from the OpenAPI specification, not written by hand. That matters for upgrade cost, which I cover later.

Installing MacPaw/OpenAI and making a first call

The README gives two installation paths. In Xcode you use File > Add Package Dependencies and enter the repository URL, then pick a dependency rule such as "Up to Next Major Version". Alternatively you add the package directly to `Package.swift`. Note that the README's snippet pins the main branch rather than a released version:

swift
dependencies: [
    .package(url: "https://github.com/MacPaw/OpenAI.git", branch: "main")
]

After the package resolves, the README's initialization example is a single line. The token comes from your OpenAI organization, and the README is explicit that it is a secret:

swift
let openAI = OpenAI(apiToken: "YOUR_TOKEN_HERE")

If you need an organization identifier or a longer timeout, the README shows the configuration form. The timeout is in seconds:

swift
let configuration = OpenAI.Configuration(token: "YOUR_TOKEN_HERE", organizationIdentifier: "YOUR_ORGANIZATION_ID_HERE", timeoutInterval: 60.0)
let openAI = OpenAI(configuration: configuration)

Once the instance exists, calls go through the protocol methods. The README's cancellation example calls `openAIClient.chats(query: .init(messages: [], model: "asd"))` inside a `Task`. That snippet is illustrative rather than a working request, since the message array is empty and the model name is a placeholder.

The README points to a Demo directory in the repository for a fuller example, and the repository listing confirms `Demo/App/` and `Demo/DemoChat/` exist. The README does not document a minimum Swift version in the text, so check the Swift Package Index badge it links for the supported toolchain range.

The API key problem the README keeps repeating

The most emphatic part of the README is not about Swift at all. It warns that the API key is a secret, that it must not be exposed in client-side code such as browsers or apps, and that production requests must be routed through your own backend server where the key can be loaded from an environment variable or a key management service. It repeats that OpenAI recommends client-side applications proxy requests through a separate backend service, because keys can access and manipulate billing, usage and organizational data.

This is a real constraint on how you use the package, not a footnote. A native iOS or macOS app that embeds `OpenAI(apiToken:)` with a literal token is doing exactly what the README warns against. The package gives you a typed client; it does not give you a safe place to keep the credential. If your architecture has no backend, this library is the wrong tool regardless of how well the Swift types fit.

The README also does not document a token refresh flow, key rotation, or any rate-limit handling strategy. Those are left to your application or your proxy.

Other providers, relaxed parsing and where it breaks

The README has a section on using the SDK with providers other than OpenAI, for services that support an OpenAI-compatible API. It names Gemini, DeepSeek, Perplexity and OpenRouter in the table of contents, and says to use the `.relaxed` parsing option on `Configuration`. It does not, in the portion available, spell out what relaxed parsing tolerates.

That is the trade-off to weigh. Strict parsing keeps you honest about the OpenAI schema; relaxed parsing buys compatibility with endpoints that only approximate it. If you are targeting a third-party provider, expect to test decoding yourself, because the README does not enumerate the differences.

The generation pipeline is the other fragile point. The Makefile comments describe three changes the project needs in a fork of apple/swift-openapi-generator that, at the time of writing, are not in the official generator: handling OpenAPI 3.1 nullable schemas expressed as `anyOf: [<schema>, { type: null }]`, matching string enum values when a `oneOf` discriminator has no explicit mapping, and falling back to structural decoding when inferred discriminator values collide. The comments cite a real spec issue, openai/openai-openapi#542, and note that without the second change, decoding a valid response throws `unknownOneOfDiscriminator`. They also mention an expected generator warning about `InputMessageResource/value2` requiring `type` even though a sibling schema declares it.

What this means for you: if you only consume the published package, you never run the generator. If you want to regenerate types against a newer `openapi.yaml`, you need that fork in place, and the Makefile comment says the changes are not upstream. That is a maintenance dependency outside this repository.

How it compares to hand-rolled URLSession calls

The alternative most Swift teams consider is writing their own thin layer over `URLSession` and `Codable`. The difference is where the schema lives. With MacPaw/OpenAI, the request and response types are generated from `openapi.yaml` using swift-openapi-generator, so they track the published specification and you get the full set of endpoints the README lists: Responses, Chat Completions, function calling, tools including MCP integration, images, audio, structured outputs, embeddings, moderations, the Assistants beta, files, and models.

A hand-rolled client typically covers the two or three endpoints a product actually uses, with types shaped to that product rather than to the OpenAI schema. That is less code to update when the API changes, and no generator fork to maintain. It is also less to learn, and it avoids dragging in a dependency for a single call.

The honest split: if you need broad endpoint coverage and want the types to follow the spec, the generated approach wins. If you need one endpoint and want zero dependencies, a small `URLSession` wrapper is easier to own. MacPaw/OpenAI sits in the first camp, and the Makefile is the price of admission for that choice.

One more difference worth noting: the package supports Swift Concurrency, closures and Combine. A hand-rolled wrapper only supports the style you write. If your codebase is already Combine-based, that is a concrete reason to take the dependency.

Maintenance, releases and licence

The repository is not archived, and the last push was on 2026-09-14. The most recent release listed is 0.5.1 from 2026-07-21, preceded by 0.5.0 on 2026-06-05 and 0.4.9 on 2026-04-30. The version numbers are still in the 0.x range, which the README reflects by labelling the Assistants section as beta.

Upgrade cost has two parts. The first is the library itself: because it tracks the REST API closely, a change in the OpenAI schema can change Swift types, and a 0.x version series offers no compatibility promise. The second is the generator fork described in the Makefile, which is only relevant if you regenerate types yourself. Consumers of the published package do not hit it.

The licence is MIT, stated in the repository and in the README's licence section. MIT is permissive and places no copyleft obligation on your application, but I am not giving legal advice; read the LICENSE file in the repository before you rely on it. The README also links a SECURITY.md at the top level, which is where the project says to look for vulnerability reporting.

Editorial conclusion

Adopt MacPaw/OpenAI if you are building a Swift or Apple-platform app and want typed calls to the OpenAI REST API without writing your own models. Do not adopt it if you need a client-side app to hold the API key directly, since the README states production requests must be routed through your own backend. Before committing, verify that the endpoints you need appear in the README's table of contents and that your toolchain resolves the package from the main branch.

Frequently asked questions

How do I install MacPaw/OpenAI?

Add it through Swift Package Manager, either in Xcode via File > Add Package Dependencies with the repository URL https://github.com/MacPaw/OpenAI.git, or by adding a `.package(url:branch:)` entry to your `Package.swift` dependencies.

How do I use my OpenAI API key with this package?

You initialize the client with `OpenAI(apiToken: "YOUR_TOKEN_HERE")`, or with an `OpenAI.Configuration` that takes the token, an organization identifier and a timeout. The README warns that the key is a secret and that production requests must be routed through your own backend rather than exposing it in client-side code.

How do I use OpenAI Whisper through MacPaw/OpenAI?

The README lists audio transcriptions and audio translations among the supported endpoints, alongside audio create speech. The available material does not include the call signatures for those methods, so check the README's Audio section in the repository.

Can I use MacPaw/OpenAI with providers other than OpenAI?

Yes. The README has a section on using the SDK with other providers that support an OpenAI-compatible API, naming Gemini, DeepSeek, Perplexity and OpenRouter, and says to use the `.relaxed` parsing option on `Configuration`.

How do I cancel a request with MacPaw/OpenAI?

For Swift Concurrency, cancel the calling task and the underlying `URLSessionDataTask` is cancelled automatically. Closure-based calls return a discardable `CancellableRequest` you hold and cancel, and Combine calls are cancelled by discarding the subscription or calling `cancel()` on it.

Official sources

  1. Issues
  2. License: MIT
  3. MacPaw/OpenAI on GitHub
  4. README
  5. Releases
Community notes

Community notes