diff --git a/Examples/GetHTML/GetHTML.swift b/Examples/GetHTML/GetHTML.swift
new file mode 100644
index 000000000..dfefa922b
--- /dev/null
+++ b/Examples/GetHTML/GetHTML.swift
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the AsyncHTTPClient open source project
+//
+// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors
+// Licensed under Apache License v2.0
+//
+// See LICENSE.txt for license information
+// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+//===----------------------------------------------------------------------===//
+
+import AsyncHTTPClient
+import NIOCore
+
+@main
+struct GetHTML {
+ static func main() async throws {
+ let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+ do {
+ let request = HTTPClientRequest(url: "https://apple.com")
+ let response = try await httpClient.execute(request, timeout: .seconds(30))
+ print("HTTP head", response)
+ let body = try await response.body.collect(upTo: 1024 * 1024) // 1 MB
+ print(String(buffer: body))
+ } catch {
+ print("request failed:", error)
+ }
+ // it is important to shutdown the httpClient after all requests are done, even if one failed
+ try await httpClient.shutdown()
+ }
+}
diff --git a/Examples/GetJSON/GetJSON.swift b/Examples/GetJSON/GetJSON.swift
new file mode 100644
index 000000000..ae58ffeaa
--- /dev/null
+++ b/Examples/GetJSON/GetJSON.swift
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the AsyncHTTPClient open source project
+//
+// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors
+// Licensed under Apache License v2.0
+//
+// See LICENSE.txt for license information
+// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+//===----------------------------------------------------------------------===//
+
+import AsyncHTTPClient
+import Foundation
+import NIOCore
+import NIOFoundationCompat
+
+struct Comic: Codable {
+ var num: Int
+ var title: String
+ var day: String
+ var month: String
+ var year: String
+ var img: String
+ var alt: String
+ var news: String
+ var link: String
+ var transcript: String
+}
+
+@main
+struct GetJSON {
+ static func main() async throws {
+ let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+ do {
+ let request = HTTPClientRequest(url: "https://xkcd.com/info.0.json")
+ let response = try await httpClient.execute(request, timeout: .seconds(30))
+ print("HTTP head", response)
+ let body = try await response.body.collect(upTo: 1024 * 1024) // 1 MB
+ // we use an overload defined in `NIOFoundationCompat` for `decode(_:from:)` to
+ // efficiently decode from a `ByteBuffer`
+ let comic = try JSONDecoder().decode(Comic.self, from: body)
+ dump(comic)
+ } catch {
+ print("request failed:", error)
+ }
+ // it is important to shutdown the httpClient after all requests are done, even if one failed
+ try await httpClient.shutdown()
+ }
+}
diff --git a/Examples/Package.swift b/Examples/Package.swift
new file mode 100644
index 000000000..58714eb5d
--- /dev/null
+++ b/Examples/Package.swift
@@ -0,0 +1,64 @@
+// swift-tools-version:5.5
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the AsyncHTTPClient open source project
+//
+// Copyright (c) 2018-2022 Apple Inc. and the AsyncHTTPClient project authors
+// Licensed under Apache License v2.0
+//
+// See LICENSE.txt for license information
+// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+//===----------------------------------------------------------------------===//
+
+import PackageDescription
+
+let package = Package(
+ name: "async-http-client-examples",
+ platforms: [
+ .macOS(.v10_15),
+ .iOS(.v13),
+ .tvOS(.v13),
+ .watchOS(.v6),
+ ],
+ products: [
+ .executable(name: "GetHTML", targets: ["GetHTML"]),
+ .executable(name: "GetJSON", targets: ["GetJSON"]),
+ .executable(name: "StreamingByteCounter", targets: ["StreamingByteCounter"]),
+ ],
+ dependencies: [
+ .package(url: "https://github.com/apple/swift-nio.git", .branch("main")),
+
+ // in real-world projects this would be
+ // .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0")
+ .package(name: "async-http-client", path: "../"),
+ ],
+ targets: [
+ // MARK: - Examples
+
+ .executableTarget(
+ name: "GetHTML",
+ dependencies: [
+ .product(name: "AsyncHTTPClient", package: "async-http-client"),
+ .product(name: "NIOCore", package: "swift-nio"),
+ ], path: "GetHTML"
+ ),
+ .executableTarget(
+ name: "GetJSON",
+ dependencies: [
+ .product(name: "AsyncHTTPClient", package: "async-http-client"),
+ .product(name: "NIOCore", package: "swift-nio"),
+ .product(name: "NIOFoundationCompat", package: "swift-nio"),
+ ], path: "GetJSON"
+ ),
+ .executableTarget(
+ name: "StreamingByteCounter",
+ dependencies: [
+ .product(name: "AsyncHTTPClient", package: "async-http-client"),
+ .product(name: "NIOCore", package: "swift-nio"),
+ ], path: "StreamingByteCounter"
+ ),
+ ]
+)
diff --git a/Examples/README.md b/Examples/README.md
new file mode 100644
index 000000000..849999f99
--- /dev/null
+++ b/Examples/README.md
@@ -0,0 +1,27 @@
+# Examples
+This folder includes a couple of Examples for `AsyncHTTPClient`.
+You can run them by opening the `Package.swift` in this folder through Xcode.
+In Xcode you can then select the scheme for the example you want run e.g. `GetHTML`.
+
+You can also run the examples from the command line by executing the follow command in this folder:
+```
+swift run GetHTML
+```
+To run other examples you can just replace `GetHTML` with the name of the example you want to run.
+
+## [GetHTML](./GetHTML/GetHTML.swift)
+
+This examples sends a HTTP GET request to `https://apple.com/` and first `await`s and `print`s the HTTP Response Head.
+Afterwards it buffers the full response body in memory and prints the response as a `String`.
+
+## [GetJSON](./GetJSON/GetJSON.swift)
+
+This examples sends a HTTP GET request to `https://xkcd.com/info.0.json` and first `await`s and `print`s the HTTP Response Head.
+Afterwards it buffers the full response body in memory, decodes the buffer using a `JSONDecoder` and `dump`s the decoded response.
+
+## [StreamingByteCounter](./StreamingByteCounter/StreamingByteCounter.swift)
+
+This examples sends a HTTP GET request to `https://apple.com/` and first `await`s and `print`s the HTTP Response Head.
+Afterwards it asynchronously iterates over all body fragments, counts the received bytes and prints a progress indicator (if the server send a content-length header).
+At the end the total received bytes are printed.
+Note that we drop all received fragment and therefore do **not** buffer the whole response body in-memory.
diff --git a/Examples/StreamingByteCounter/StreamingByteCounter.swift b/Examples/StreamingByteCounter/StreamingByteCounter.swift
new file mode 100644
index 000000000..dc340d14b
--- /dev/null
+++ b/Examples/StreamingByteCounter/StreamingByteCounter.swift
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the AsyncHTTPClient open source project
+//
+// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors
+// Licensed under Apache License v2.0
+//
+// See LICENSE.txt for license information
+// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+//===----------------------------------------------------------------------===//
+
+import AsyncHTTPClient
+import NIOCore
+
+@main
+struct StreamingByteCounter {
+ static func main() async throws {
+ let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+ do {
+ let request = HTTPClientRequest(url: "https://apple.com")
+ let response = try await httpClient.execute(request, timeout: .seconds(30))
+ print("HTTP head", response)
+
+ // if defined, the content-length headers announces the size of the body
+ let expectedBytes = response.headers.first(name: "content-length").flatMap(Int.init)
+
+ var receivedBytes = 0
+ // asynchronously iterates over all body fragments
+ // this loop will automatically propagate backpressure correctly
+ for try await buffer in response.body {
+ // For this example, we are just interested in the size of the fragment
+ receivedBytes += buffer.readableBytes
+
+ if let expectedBytes = expectedBytes {
+ // if the body size is known, we calculate a progress indicator
+ let progress = Double(receivedBytes) / Double(expectedBytes)
+ print("progress: \(Int(progress * 100))%")
+ }
+ }
+ print("did receive \(receivedBytes) bytes")
+ } catch {
+ print("request failed:", error)
+ }
+ // it is important to shutdown the httpClient after all requests are done, even if one failed
+ try await httpClient.shutdown()
+ }
+}