Other Language SDKs at a Glance
Python and TypeScript are two members of a much larger family.
Search across all documentation pages
Python and TypeScript are two members of a much larger family.
AWS maintains first-party SDKs for Go, Java, .NET, Rust, and more, all generated from the same service models as boto3 and the AWS SDK for JavaScript v3. If a team already lives in one of these languages, its SDK is the natural choice.
This page is a quick tour: the same ListBuckets operation in each, plus what to know about packaging and maturity.
The goal: recognize each SDK's shape so you can read and choose across a polyglot org.
The approach is to anchor on one familiar operation. Here is the boto3 and SDK v3 baseline you already know, so the other languages have something to map onto.
# --- Python (boto3) ---
import boto3
s3 = boto3.client("s3")
for bucket in s3.list_buckets()["Buckets"]:
print(bucket["Name"])// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({});
const res = await s3.send(new ListBucketsCommand({}));
for (const bucket of res.Buckets ?? []) console.log(bucket.Name);Every SDK below performs this same ListBuckets call. Watch how the operation and Buckets/Name fields survive the translation.
Here is the same operation in the four other major SDKs. The imports and idioms change; the operation does not.
// --- Go (aws-sdk-go-v2) ---
// go get github.com/aws/aws-sdk-go-v2/config github.com/aws/aws-sdk-go-v2/service/s3
cfg, _ := config.LoadDefaultConfig(context.TODO())
client := s3.NewFromConfig(cfg)
out, _ := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
for _, b := range out.Buckets {
fmt.Println(*b.Name)
}// --- Java (AWS SDK for Java 2.x) ---
// Maven: software.amazon.awssdk:s3
S3Client s3 = S3Client.create();
ListBucketsResponse res = s3.listBuckets();
res.buckets().forEach(b -> System.out.println(b.name()));// --- .NET (AWS SDK for .NET) ---
// NuGet: AWSSDK.S3
using var client = new AmazonS3Client();
var res = await client.ListBucketsAsync(new ListBucketsRequest());
foreach (var b in res.Buckets) Console.WriteLine(b.BucketName);// --- Rust (AWS SDK for Rust) ---
// Cargo: aws-config, aws-sdk-s3
let cfg = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let client = aws_sdk_s3::Client::new(&cfg);
let res = client.list_buckets().send().await?;
for b in res.buckets() {
println!("{}", b.name().unwrap_or_default());
}The operation name maps cleanly: ListBuckets becomes ListBuckets (Go), listBuckets (Java), ListBucketsAsync (.NET), and list_buckets().send() (Rust). The bucket name field is Name/name/BucketName depending on convention.
Each SDK reflects its language's ecosystem, but the design trend is toward modularity.
Go (aws-sdk-go-v2) is the current Go SDK line, and it is modular: you go get a separate service/<name> module per service. It uses explicit context.Context and returns errors as values, matching Go idioms. Config loads via config.LoadDefaultConfig.
Java (AWS SDK for Java 2.x) is the modern rewrite of the Java SDK, also modular - you depend on software.amazon.awssdk:<service> per service. It uses a builder pattern (S3Client.builder()), non-blocking async clients, and a pluggable HTTP layer. The older 1.x line (com.amazonaws) still exists but 2.x is the recommended default.
.NET (AWS SDK for .NET) ships per-service NuGet packages under the AWSSDK.* namespace (AWSSDK.S3, AWSSDK.DynamoDBv2). It is idiomatic async with ...Async methods returning Task, and integrates with .NET dependency injection.
Rust (AWS SDK for Rust) is generally available and modular by crate (aws-sdk-s3, aws-sdk-dynamodb), built on aws-config for credentials and Tokio for async. It uses a fluent builder-and-send() call style and requires a BehaviorVersion so upgrades are explicit.
The through-line: three of the four (Go v2, Java 2.x, Rust) are modular per-service, echoing the same reasoning behind AWS SDK for JavaScript v3. boto3's all-in-one monolith is actually the outlier, justified by server-side Python's different constraints.
Maturity is high across the board. Go, Java, and .NET SDKs are long-established; the Rust SDK reached general availability more recently but is first-party and production-ready. All are code-generated from the shared models, so operation coverage tracks closely.
aws-sdk-go (v1) and aws-sdk-go-v2 are different module trees with different APIs; new code should use v2.com.amazonaws (1.x) and software.amazon.awssdk (2.x) coexist; 2.x is modular and recommended, so do not copy 1.x snippets into a 2.x project.AWSSDK.<Service> package, not a meta-package, to keep dependencies tight.BehaviorVersion; omitting it is a compile-time or runtime error by design, so upgrades never change behavior silently.Name vs name vs BucketName), so read that SDK's types.If your team is not on Go, Java, .NET, or Rust, other first-party SDKs exist, including PHP, Ruby, Kotlin, C++, and Swift.
They follow the same pattern: generated from shared models, per-service or monolithic depending on the ecosystem, with language-idiomatic surfaces.
For a workload where no SDK fits - an obscure runtime or a shell context - the AWS CLI (built on botocore) or a signed raw HTTPS request are fallbacks, though both are lower-level than a native SDK.
For most polyglot teams, though, the right move is simply the first-party SDK for the language the service already uses. That keeps one language per service and avoids bolting on a second runtime.
Yes. The current line is aws-sdk-go-v2, which is modular per service. The older aws-sdk-go (v1) still exists, but v2 is the recommended default for new code.
AWS SDK for Java 2.x (software.amazon.awssdk). It is the modern, modular, builder-based rewrite. The 1.x line (com.amazonaws) is legacy and should not be used for new projects.
As per-service NuGet packages under AWSSDK.*, such as AWSSDK.S3. Operations are async (...Async returning Task) and integrate with standard .NET dependency injection.
Yes. The AWS SDK for Rust is generally available and first-party, modular by crate (aws-sdk-s3), built on aws-config and Tokio. It requires an explicit BehaviorVersion.
Effectively yes. They are code-generated from the same service models as boto3 and SDK v3, so operation coverage is near-identical; only language idioms and packaging differ.
The same reasoning as AWS SDK for JavaScript v3: modular packages keep dependencies and build artifacts small. boto3's monolith is the outlier, justified by server-side Python's constraints.
An explicit marker that pins default behaviors so future SDK upgrades do not change them silently. You pass it when loading config; omitting it is intentionally an error.
The operation names are shared, but field casing follows each language - Name in Python, name in Java, BucketName in .NET. Always check the target SDK's generated types.
Yes - PHP, Ruby, Kotlin, C++, Swift, and more are first-party. They follow the same generated, per-service or monolithic pattern with language-idiomatic surfaces.
By the language the workload already uses. Capability parity is high, so match the SDK to the team and runtime rather than chasing feature differences that largely do not exist.
Yes. Because they all call the same AWS services, an object written by a Python job is readable by a Go, Java, .NET, or Rust service without any special interop.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Reviewed by Chris St. John·Last updated Jul 23, 2026