diff --git a/Sources/ElixxirDAppsSDK/ClientLoader.swift b/Sources/ElixxirDAppsSDK/ClientLoader.swift
new file mode 100644
index 0000000000000000000000000000000000000000..632f01070f054694ab261c5b045e6956060b29a2
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientLoader.swift
@@ -0,0 +1,30 @@
+import Bindings
+
+public struct ClientLoader {
+  public var load: (URL, Data) throws -> Client
+
+  public func callAsFunction(directoryURL: URL, password: Data) throws -> Client {
+    try load(directoryURL, password)
+  }
+}
+
+extension ClientLoader {
+  public static let live = ClientLoader { directoryURL, password in
+    var error: NSError?
+    let bindingsClient = BindingsLogin(directoryURL.path, password, &error)
+    if let error = error { throw error }
+    guard let bindingsClient = bindingsClient else {
+      throw BindingsLoginUnknownError()
+    }
+    return Client.live(bindingsClient: bindingsClient)
+  }
+}
+
+#if DEBUG
+extension ClientLoader {
+  public static let failing = ClientLoader { _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/Errors.swift b/Sources/ElixxirDAppsSDK/Errors.swift
index 94f93f982e58bd8a3e26c4494c96f88697a6fb70..d28f5bafc0e6843d9a43a6f10171c5fa35596437 100644
--- a/Sources/ElixxirDAppsSDK/Errors.swift
+++ b/Sources/ElixxirDAppsSDK/Errors.swift
@@ -13,3 +13,7 @@ public struct PasswordStorageMissingPasswordError: Error, Equatable {
 public struct BindingsNewClientUnknownError: Error, Equatable {
   public init() {}
 }
+
+public struct BindingsLoginUnknownError: Error, Equatable {
+  public init() {}
+}