diff --git a/Sources/ClientRuntime/Client/Client.swift b/Sources/ClientRuntime/Client/Client.swift
index 424d580fe..f0441a1d1 100644
--- a/Sources/ClientRuntime/Client/Client.swift
+++ b/Sources/ClientRuntime/Client/Client.swift
@@ -4,7 +4,9 @@
 //
 // SPDX-License-Identifier: Apache-2.0
 //
+
 public protocol Client {
     associatedtype Config: ClientConfiguration
+
     init(config: Config)
 }
diff --git a/Sources/ClientRuntime/Client/ClientBuilder.swift b/Sources/ClientRuntime/Client/ClientBuilder.swift
index e8f007c2a..2124d5ffc 100644
--- a/Sources/ClientRuntime/Client/ClientBuilder.swift
+++ b/Sources/ClientRuntime/Client/ClientBuilder.swift
@@ -4,29 +4,36 @@
 //
 // SPDX-License-Identifier: Apache-2.0
 //
+
 public class ClientBuilder<ClientType: Client> {
 
-    private var plugins: [Plugin]
+    private struct PluginContainer: Plugin {
+        let plugin: any Plugin<ClientType.Config>
 
-    public init(defaultPlugins: [Plugin] = []) {
-        self.plugins = defaultPlugins
+        func configureClient(clientConfiguration: inout ClientType.Config) async throws {
+            try await plugin.configureClient(clientConfiguration: &clientConfiguration)
+        }
     }
 
-    public func withPlugin(_ plugin: any Plugin) -> ClientBuilder<ClientType> {
-        self.plugins.append(plugin)
+    private var plugins = [PluginContainer]()
+
+    public init() {}
+
+    public func withPlugin<P: Plugin>(_ plugin: P) -> ClientBuilder<ClientType> where P.Config == ClientType.Config {
+        self.plugins.append(PluginContainer(plugin: plugin))
         return self
     }
 
     public func build() async throws -> ClientType {
-        let configuration = try await resolve(plugins: self.plugins)
+        let configuration = try await resolve()
         return ClientType(config: configuration)
     }
 
-    func resolve(plugins: [any Plugin]) async throws -> ClientType.Config {
-        let clientConfiguration = try await ClientType.Config()
+    private func resolve() async throws -> ClientType.Config {
+        var config = try await ClientType.Config()
         for plugin in plugins {
-            try await plugin.configureClient(clientConfiguration: clientConfiguration)
+            try await plugin.configureClient(clientConfiguration: &config)
         }
-        return clientConfiguration
+        return config
     }
 }
diff --git a/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift b/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift
index 399878c9c..de5d9e981 100644
--- a/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift
+++ b/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift
@@ -34,7 +34,7 @@ public protocol DefaultClientConfiguration: ClientConfiguration {
     /// Adds an `InterceptorProvider` that will be used to provide interceptors for all operations.
     ///
     /// - Parameter provider: The `InterceptorProvider` to add.
-    func addInterceptorProvider(_ provider: InterceptorProvider)
+    mutating func addInterceptorProvider(_ provider: InterceptorProvider)
 
     /// TODO(plugins): Add Checksum, etc.
 }
diff --git a/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift b/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift
index 5b390a4e5..f53554917 100644
--- a/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift
+++ b/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift
@@ -39,5 +39,5 @@ public protocol DefaultHttpClientConfiguration: ClientConfiguration {
     /// Adds a `HttpInterceptorProvider` that will be used to provide interceptors for all HTTP operations.
     ///
     /// - Parameter provider: The `HttpInterceptorProvider` to add.
-    func addInterceptorProvider(_ provider: HttpInterceptorProvider)
+    mutating func addInterceptorProvider(_ provider: HttpInterceptorProvider)
 }
diff --git a/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift b/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift
index 4b3d016ff..4540cc02d 100644
--- a/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift
+++ b/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift
@@ -7,7 +7,7 @@
 
 import SmithyHTTPAuthAPI
 
-public class AuthSchemePlugin: Plugin {
+public class AuthSchemePlugin<Config: DefaultHttpClientConfiguration>: Plugin {
 
     private var authSchemes: [AuthScheme]?
 
@@ -21,14 +21,12 @@ public class AuthSchemePlugin: Plugin {
         self.authSchemes = authSchemes
     }
 
-    public func configureClient(clientConfiguration: ClientConfiguration) {
-        if var config = clientConfiguration as? DefaultHttpClientConfiguration {
-            if self.authSchemes != nil {
-                config.authSchemes = self.authSchemes!
-            }
-            if self.authSchemeResolver != nil {
-                config.authSchemeResolver = self.authSchemeResolver!
-            }
+    public func configureClient(clientConfiguration: inout Config) {
+        if let authSchemes {
+            clientConfiguration.authSchemes = authSchemes
+        }
+        if let authSchemeResolver {
+            clientConfiguration.authSchemeResolver = authSchemeResolver
         }
     }
 }
diff --git a/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift b/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift
index df080b1c6..5b35940de 100644
--- a/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift
+++ b/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift
@@ -7,23 +7,17 @@
 
 import struct SmithyRetries.DefaultRetryStrategy
 
-public class DefaultClientPlugin: Plugin {
+public class DefaultClientPlugin<Config: DefaultClientConfiguration & DefaultHttpClientConfiguration>: Plugin {
+    typealias DefaultRuntimeConfig = DefaultSDKRuntimeConfiguration<DefaultRetryStrategy, DefaultRetryErrorInfoProvider>
+
     public init() {}
-    public func configureClient(clientConfiguration: ClientConfiguration) {
-        if var config = clientConfiguration as? DefaultClientConfiguration {
-            config.retryStrategyOptions =
-                DefaultSDKRuntimeConfiguration<DefaultRetryStrategy, DefaultRetryErrorInfoProvider>
-                    .defaultRetryStrategyOptions
-        }
 
-        if var config = clientConfiguration as? DefaultHttpClientConfiguration {
-            let httpClientConfiguration =
-                DefaultSDKRuntimeConfiguration<DefaultRetryStrategy, DefaultRetryErrorInfoProvider>
-                    .defaultHttpClientConfiguration
-            config.httpClientConfiguration = httpClientConfiguration
-            config.httpClientEngine =
-                DefaultSDKRuntimeConfiguration<DefaultRetryStrategy, DefaultRetryErrorInfoProvider>
-                    .makeClient(httpClientConfiguration: httpClientConfiguration)
-        }
+    public func configureClient(clientConfiguration: inout Config) async throws {
+        clientConfiguration.retryStrategyOptions = DefaultRuntimeConfig.defaultRetryStrategyOptions
+        let httpClientConfiguration = DefaultRuntimeConfig .defaultHttpClientConfiguration
+        clientConfiguration.httpClientConfiguration = httpClientConfiguration
+        clientConfiguration.httpClientEngine = DefaultRuntimeConfig.makeClient(
+            httpClientConfiguration: httpClientConfiguration
+        )
     }
 }
diff --git a/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift b/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift
index c7aea9893..620eba4af 100644
--- a/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift
+++ b/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift
@@ -8,10 +8,8 @@
 import protocol SmithyHTTPAPI.HTTPClient
 import struct SmithyRetries.DefaultRetryStrategy
 
-public class DefaultHttpClientPlugin: Plugin {
-
+public class DefaultHttpClientPlugin<Config: DefaultHttpClientConfiguration>: Plugin {
     var httpClientConfiguration: HttpClientConfiguration
-
     var httpClient: HTTPClient
 
     public init(httpClient: HTTPClient, httpClientConfiguration: HttpClientConfiguration) {
@@ -27,10 +25,8 @@ public class DefaultHttpClientPlugin: Plugin {
         )
     }
 
-    public func configureClient(clientConfiguration: ClientConfiguration) {
-        if var config = clientConfiguration as? DefaultHttpClientConfiguration {
-            config.httpClientConfiguration = self.httpClientConfiguration
-            config.httpClientEngine = self.httpClient
-        }
+    public func configureClient(clientConfiguration: inout Config) {
+        clientConfiguration.httpClientConfiguration = self.httpClientConfiguration
+        clientConfiguration.httpClientEngine = self.httpClient
     }
 }
diff --git a/Sources/ClientRuntime/Plugins/Plugin.swift b/Sources/ClientRuntime/Plugins/Plugin.swift
index 0e6482ee1..b6c3969b5 100644
--- a/Sources/ClientRuntime/Plugins/Plugin.swift
+++ b/Sources/ClientRuntime/Plugins/Plugin.swift
@@ -5,6 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0
 //
 
-public protocol Plugin {
-    func configureClient(clientConfiguration: ClientConfiguration) async throws
+public protocol Plugin<Config> {
+    associatedtype Config: ClientConfiguration
+
+    func configureClient(clientConfiguration: inout Config) async throws
 }
diff --git a/Sources/ClientRuntime/Plugins/RetryPlugin.swift b/Sources/ClientRuntime/Plugins/RetryPlugin.swift
index 1799fa77e..9b04508c7 100644
--- a/Sources/ClientRuntime/Plugins/RetryPlugin.swift
+++ b/Sources/ClientRuntime/Plugins/RetryPlugin.swift
@@ -7,7 +7,7 @@
 
 import struct SmithyRetriesAPI.RetryStrategyOptions
 
-public class RetryPlugin: Plugin {
+public class RetryPlugin<Config: DefaultClientConfiguration>: Plugin {
 
     private var retryStrategyOptions: RetryStrategyOptions
 
@@ -15,9 +15,7 @@ public class RetryPlugin: Plugin {
         self.retryStrategyOptions = retryStrategyOptions
     }
 
-    public func configureClient(clientConfiguration: ClientConfiguration) {
-        if var config = clientConfiguration as? DefaultClientConfiguration {
-            config.retryStrategyOptions = self.retryStrategyOptions
-        }
+    public func configureClient(clientConfiguration: inout Config) {
+        clientConfiguration.retryStrategyOptions = self.retryStrategyOptions
     }
 }
diff --git a/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift b/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift
index b9bd14066..ea368b257 100644
--- a/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift
+++ b/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0
 //
 
-public class TelemetryPlugin: Plugin {
+public class TelemetryPlugin<Config: DefaultClientConfiguration>: Plugin {
+
     private let telemetryProvider: TelemetryProvider
 
     public init(telemetryProvider: TelemetryProvider) {
@@ -26,10 +27,8 @@ public class TelemetryPlugin: Plugin {
         )
     }
 
-    public func configureClient(clientConfiguration: ClientConfiguration) {
-        if var config = clientConfiguration as? DefaultClientConfiguration {
-            config.telemetryProvider = self.telemetryProvider
-        }
+    public func configureClient(clientConfiguration: inout Config) {
+        clientConfiguration.telemetryProvider = self.telemetryProvider
     }
 }
 
diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt
index a8b91917b..f756daa9f 100644
--- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt
+++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt
@@ -58,6 +58,7 @@ class DefaultClientConfiguration : ClientConfiguration {
                     listOf(
                         FunctionParameter.NoLabel("provider", ClientRuntimeTypes.Core.InterceptorProvider),
                     ),
+                isMutating = true,
             ),
         )
 }
diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt
index cb2746867..a88e1c776 100644
--- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt
+++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt
@@ -74,6 +74,7 @@ class DefaultHttpClientConfiguration : ClientConfiguration {
                     listOf(
                         FunctionParameter.NoLabel("provider", ClientRuntimeTypes.Core.HttpInterceptorProvider),
                     ),
+                isMutating = true,
             ),
         )
 }
diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt
index 93e4ebe48..f31ea8d81 100644
--- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt
+++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt
@@ -75,30 +75,25 @@ open class HttpProtocolServiceClient(
                 ClientRuntimeTypes.Core.ClientBuilder,
                 serviceSymbol.name,
             ) {
-                writer.openBlock(
-                    "return \$N<\$L>(defaultPlugins: [",
-                    "])",
+                writer.write(
+                    "return \$N<\$L>()",
                     ClientRuntimeTypes.Core.ClientBuilder,
                     serviceSymbol.name,
-                ) {
-                    val defaultPlugins: MutableList<Plugin> = mutableListOf(DefaultClientPlugin())
+                )
+                writer.indent()
+                val defaultPlugins: MutableList<Plugin> = mutableListOf(DefaultClientPlugin())
 
-                    ctx.integrations
-                        .flatMap { it.plugins(serviceConfig) }
-                        .filter { it.isDefault }
-                        .onEach { defaultPlugins.add(it) }
+                ctx.integrations
+                    .flatMap { it.plugins(serviceConfig) }
+                    .filter { it.isDefault }
+                    .onEach { defaultPlugins.add(it) }
 
-                    val pluginsIterator = defaultPlugins.iterator()
+                val pluginsIterator = defaultPlugins.iterator()
 
-                    while (pluginsIterator.hasNext()) {
-                        pluginsIterator.next().customInitialization(writer)
-                        if (pluginsIterator.hasNext()) {
-                            writer.write(",")
-                        }
-                    }
-
-                    writer.unwrite(",\n").write("")
+                while (pluginsIterator.hasNext()) {
+                    writer.write(".withPlugin(\$L)", pluginsIterator.next().customInitialization(writer))
                 }
+                writer.dedent()
             }
         }
         writer.write("")
@@ -113,7 +108,7 @@ open class HttpProtocolServiceClient(
                 .joinToString(" & ")
 
         writer.openBlock(
-            "public class \$LConfiguration: \$L {",
+            "public struct \$LConfiguration: \$L {",
             "}",
             serviceConfig.clientName.toUpperCamelCase(),
             clientConfigurationProtocols,
@@ -156,7 +151,7 @@ open class HttpProtocolServiceClient(
     open fun overrideConfigProperties(properties: List<ConfigProperty>): List<ConfigProperty> = properties
 
     private fun renderEmptyAsynchronousConfigInitializer(properties: List<ConfigProperty>) {
-        writer.openBlock("public convenience required init() async throws {", "}") {
+        writer.openBlock("public init() async throws {", "}") {
             writer.openBlock("try await self.init(", ")") {
                 properties.forEach { property ->
                     writer.write("\$L: nil,", property.name)
@@ -219,7 +214,7 @@ open class HttpProtocolServiceClient(
     }
 
     private fun renderSynchronousConfigInitializer(properties: List<ConfigProperty>) {
-        writer.openBlock("public convenience init(", ") throws {") {
+        writer.openBlock("public init(", ") throws {") {
             properties.forEach { property ->
                 writer.write("\$L: \$N = nil,", property.name, property.type.toOptional())
             }
@@ -246,7 +241,7 @@ open class HttpProtocolServiceClient(
     private fun renderAsynchronousConfigInitializer(properties: List<ConfigProperty>) {
         if (properties.none { it.default?.isAsync == true }) return
 
-        writer.openBlock("public convenience init(", ") async throws {") {
+        writer.openBlock("public init(", ") async throws {") {
             properties.forEach { property ->
                 writer.write("\$L: \$L = nil,", property.name, property.type.toOptional().renderSwiftType(writer))
             }
diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/Plugin.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/Plugin.kt
index 74ad6e5bb..c7e073ab8 100644
--- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/Plugin.kt
+++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/Plugin.kt
@@ -8,9 +8,7 @@ interface Plugin {
     val isDefault: Boolean
         get() = false
 
-    fun customInitialization(writer: SwiftWriter) {
-        writer.writeInline("\$N()", className)
-    }
+    fun customInitialization(writer: SwiftWriter): String = writer.format("\$N()", className)
 
     fun render(
         ctx: ProtocolGenerator.GenerationContext,
diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt
index d3b3ee3a2..ba2f86827 100644
--- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt
+++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt
@@ -20,18 +20,25 @@ data class Function(
     val accessModifier: AccessModifier = AccessModifier.Public,
     val isAsync: Boolean = false,
     val isThrowing: Boolean = false,
+    val isMutating: Boolean = false,
 ) {
     /**
      * Render this function using the given writer.
      */
     fun render(writer: SwiftWriter) {
+        val renderedMutating = "mutating ".takeIf { isMutating } ?: ""
         val renderedParameters = parameters.joinToString(", ") { it.rendered(writer) }
         val renderedAsync = if (isAsync) "async " else ""
         val renderedThrows = if (isThrowing) "throws " else ""
         val renderedReturnType = returnType?.let { writer.format("-> \$N ", it) } ?: ""
         writer.openBlock(
-            "${accessModifier.renderedRightPad()}func $name($renderedParameters) $renderedAsync$renderedThrows$renderedReturnType{",
+            "\$L\$Lfunc \$L(\$L) \$L$renderedThrows$renderedReturnType{",
             "}",
+            accessModifier.renderedRightPad(),
+            renderedMutating,
+            name,
+            renderedParameters,
+            renderedAsync,
         ) {
             renderBody.accept(writer)
         }
diff --git a/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt b/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt
index 2ace6c4f3..621f66e31 100644
--- a/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt
+++ b/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt
@@ -38,7 +38,7 @@ public class RestJsonProtocolClient: ClientRuntime.Client {
 
 extension RestJsonProtocolClient {
 
-    public class RestJsonProtocolClientConfiguration: ClientRuntime.DefaultClientConfiguration & ClientRuntime.DefaultHttpClientConfiguration {
+    public struct RestJsonProtocolClientConfiguration: ClientRuntime.DefaultClientConfiguration & ClientRuntime.DefaultHttpClientConfiguration {
         public var telemetryProvider: ClientRuntime.TelemetryProvider
         public var retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions
         public var clientLogMode: ClientRuntime.ClientLogMode
@@ -80,7 +80,7 @@ extension RestJsonProtocolClient {
             self.httpInterceptorProviders = httpInterceptorProviders
         }
 
-        public convenience init(
+        public init(
             telemetryProvider: ClientRuntime.TelemetryProvider? = nil,
             retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil,
             clientLogMode: ClientRuntime.ClientLogMode? = nil,
@@ -110,7 +110,7 @@ extension RestJsonProtocolClient {
             )
         }
 
-        public convenience required init() async throws {
+        public init() async throws {
             try await self.init(
                 telemetryProvider: nil,
                 retryStrategyOptions: nil,
@@ -131,20 +131,19 @@ extension RestJsonProtocolClient {
             return ""
         }
 
-        public func addInterceptorProvider(_ provider: ClientRuntime.InterceptorProvider) {
+        public mutating func addInterceptorProvider(_ provider: ClientRuntime.InterceptorProvider) {
             self.interceptorProviders.append(provider)
         }
 
-        public func addInterceptorProvider(_ provider: ClientRuntime.HttpInterceptorProvider) {
+        public mutating func addInterceptorProvider(_ provider: ClientRuntime.HttpInterceptorProvider) {
             self.httpInterceptorProviders.append(provider)
         }
 
     }
 
     public static func builder() -> ClientRuntime.ClientBuilder<RestJsonProtocolClient> {
-        return ClientRuntime.ClientBuilder<RestJsonProtocolClient>(defaultPlugins: [
-            ClientRuntime.DefaultClientPlugin()
-        ])
+        return ClientRuntime.ClientBuilder<RestJsonProtocolClient>()
+            .withPlugin(ClientRuntime.DefaultClientPlugin())
     }
 }
 """