Introducing Swift Configuration

Hi Swift Community!

Today, we’re pleased to announce the initial release of Swift Configuration: a new library that provides a unified approach to reading configuration in your Swift applications.

Configuration management has long been a challenge across different sources and environments. Previously, configuration in Swift had to be manually stitched together from environment variables, command-line arguments, JSON files, and external systems. Swift Configuration creates a common interface for configuration, enabling you to:

  • Read configuration the same way across your codebase using a single configuration reader API that’s usable from both applications and libraries.

  • Quickly get started with a few lines of code using built-in providers for environment variables, command-line arguments, JSON and YAML files, and in-memory values.

  • Build and share custom configuration providers using a public ConfigProvider protocol that anyone can implement and share.

Swift Configuration excels in the Swift server ecosystem, where configuration is often read from multiple systems and tools. The library is equally useful in command-line tools, GUI applications, and libraries wherever flexible configuration management is needed.

Getting started

Swift Configuration's key strength lies in its ability to combine multiple configuration providers into a coherent hierarchy. This allows you to establish sensible defaults while providing clean override mechanisms for different deployment scenarios.

For example, if you have default configuration in JSON:

{
  "http": {
    "timeout": 30
  }
}

And want to be able to provide an override using an environment variable:

# Environment variables:
HTTP_TIMEOUT=15

The example below creates the two relevant providers, and uses them to resolve a value for the HTTP timeout:

let config = ConfigReader(providers: [
    EnvironmentVariablesProvider(),
    try await JSONProvider(filePath: "/etc/config.json")
])
let httpTimeout = config.int(forKey: "http.timeout", default: 60)
print(httpTimeout) // prints 15

The resolver checks providers in the order you specify, so environment variables take precedence over JSON configuration, which in turn overrides your fallback defaults. This eliminates ambiguity about which configuration source is actually being used.

As your configuration needs evolve, enable access logging to track where values are accessed in your code and which providers are responding. This transparency helps maintain confidence even in complex configuration hierarchies.

Advanced capabilities

While the library prioritizes simplicity for basic use cases, it includes powerful features for production environments:

The complete documentation covers these features in detail.

Community feedback welcome

With version 0.1.0 now available, we're eager to see how the community integrates Swift Configuration into real-world projects. Your experience with different use cases, configuration patterns, and deployment scenarios will help shape the library's evolution.

Please try integrating Swift Configuration into your applications, tools, and libraries, and share your feedback through GitHub issues, pull requests, or Swift Forums discussions.

Stability note

Since this is a pre-1.0 release, libraries that need API stability may want to wait for the 1.0 release, which we expect to ship in the next few months. However, we encourage experimentation and integration testing on development branches – your feedback ensures the 1.0 API meets your requirements.

Links

70 Likes

Okay now this is awesome. We spun up our own configuration reader “library” but maybe this could be a thing to look at!

4 Likes

:eyes: If anyone’s headed to ServerSide.swift next week, check out Honza’s talk on Friday at 16:15 on Swift Configuration – Schedule | ServerSide.swift Conference !

PRO TIP: if you still need a ticket, use “COMMUNITY15“ for 15% off :wink:

12 Likes

Awesome work :tada:

2 Likes

And yet the choice of the abbreviation Config instead of the full Configuration is unclear. In Swift, full names without abbreviations seem to be preferred; the package itself is called swift-configuration, and even the folders in the sources start with Configuration. It almost makes you want to write a typealias when importing this library.

2 Likes

“Config" is only ever used as a type prefix, never a standalone term.

That’s exactly what worries me: choosing an abbreviation for the type prefix instead of using the full word.

Can we use this for ios applications? If so do you have any use case or some doc?

1 Like

Hi! Yes you can. This is just an initial release announcement but we will add more examples to cover difference use cases in the future.

3 Likes

Yes, can be used in iOS apps. I filed an issue for us to add an example, but the idea is that you create a ConfigReader at the top level, eg in your SwiftUI.App struct and then pass it down to the views as a parameter.

5 Likes

Can you access this in a SwiftPM’s Package.swift? That would be incredibly useful!

You can't and in general dynamic configuration based on external sources should be avoided in Package.swift manifest files. The package manager and build system can't reason about what is driving the dynamic configuration of the package. Usage of env variables inside the package manifest can easily lead to caching problems.

If you need more dynamism in the manifest prefer to use package traits.

3 Likes

Can this interoperate with Argument Parser for command line arguments? How do the two interact?

3 Likes

I'm really excited about this, fantastic work! :tada: I'm eager to try out to implement a Vault/OpenbaoProvider with swift-configuration and vault-courier.

2 Likes

Awesome! When you do, we can link to the repo from Swift Configuration's README. I'm excited to see community providers pop up.

1 Like

ConfigReader is appropriate when using multiple sources or you need to read configuration from libraries.

If you only need CLI arguments and are reading from an application/tool, I recommend using Swift Argument Parser - it's a better, more optimized experience for the CLI use case.

@nnnnnnnn and I discussed ideas of how, with some additional APIs, Swift Argument Parser could actually power the CommandLineArgumentsProvider under the hood. We can still do that, the public API of CommandLineArgumentsProvider wouldn't be affected. So we can do this before or after 1.0.

1 Like

I too am excited about this! Any chance we could get the yaml provider moved to a separate repo for a future stable release? I like the idea of having minimal dependencies around the providers, especially for a non-SSWG or non-Apple dependency.

With package traits, you control which providers you get. The YAML provider is opt-in, so unless you explicitly enable it, you won't get it and the Yams dependency won't be pulled in.

1 Like

Oh very cool, I missed that detail. Thanks!

This is super exciting news! I love this development!

I guess the stringly-keyed API is a lot more flexible. Although I’d really be interested in a typesafe reader variant. Instead of relying on documentation and manual enforcement to keep key names, key types, and their defaults consistent.

Although that would probably need to employ a macro.


I have a small exploration on this subject here:

2 Likes