Generates Unison client code from Smithy service models. Produces client modules, type definitions, and HTTP request/response handling for service operations.
Reference: https://smithy.io/2.0/index.html
- Smithy Build plugin integration
- Support for Smithy Interface Definition Language (IDL) and JSON AST
- Structure generation → Unison record types
- Enum generation → Unison sum types with
toText/fromTextfunctions - Union generation → Unison sum types with payloads
- Error type generation with
toFailureconversion functions - Service-level error sum types with parsing functions
- Automatic type generation for all services (AWS and non-AWS)
- REST-XML protocol (S3, CloudFront, Route 53)
- Full operation implementation (all 106 S3 operations)
- HTTP binding traits:
@http,@httpLabel,@httpQuery,@httpHeader,@httpPayload,@httpResponseCode - Request serialization / Response deserialization
- Error parsing
- AWS JSON 1.0/1.1 protocols (DynamoDB, Lambda, Kinesis)
- Full operation implementation with request serialization and response deserialization
- Nested structure serializer/deserializer generation
- Error parsing (JSON error responses with
__typefield) - Service error union types with exception handling
- REST-JSON protocol (EventBridge, Step Functions, API Gateway, Lambda)
- Full operation implementation with HTTP bindings and JSON serialization/deserialization
- Complete response deserializer generation (structures, enums, lists, maps, unions)
- Path parameter substitution and query string building
- HTTP header extraction and body serialization
- Error parsing with multiple format support
- Resource operation support
- Reserved keyword escaping (backtick syntax)
- AWS Query protocol (SQS, SNS, RDS)
- Full operation implementation with XML request serialization and response deserialization
- Form-encoded parameter serialization with proper Query format
- XML map and list extraction with @xmlFlattened trait support
- Structure list serialization with required/optional field handling
- Error parsing from XML error responses
- EC2 Query protocol (EC2)
- Extends AWS Query with EC2-specific response and error format handling
- Custom response wrapper navigation
- EC2-specific error parsing structure
- AWS SigV4 request signing - Complete implementation of Signature Version 4
- Shared credential types (
aws.config.Credentials) with anonymous, basic, and temporary credential support - Signing config (
aws.sigv4.SigningConfig) with region and service from shared Config - Canonical request building
- Signing key derivation (HMAC-SHA256 chain)
- Authorization header generation
- Shared credential types (
- Shared configuration (
aws.config.Config) with type-safe region and endpoint handling - Credential provider chain (environment variables, config files) with
aws.config.Credentials - Retry logic with exponential backoff and jitter
- Pagination with automatic helper function generation and token field inference
Check out AWS_SDK_SUPPORT.md with a full list of AWS SDK features and their support status in smithy-unison.
- Java 11+
- Gradle 8.0+
- Unison (UCM)
- Smithy CLI
- Docker and Terraform (for testing)
make buildRun generator tests:
make testCheckout examples for fully functional Unison demo.
Run any example with:
make examples/<example_name> # <----- without trailing slashThe *-demo examples generate client code from the official AWS SDK smithy models and create AWS infrastructure using LocalStack. The demo app then executes functions from the generated client against the mocked infrastructure.
| make examples/s3-demo |
| make examples/dynamodb-demo |
| make examples/sqs-demo |
| make examples/kinesis-demo |
| make examples/sns-demo |
| make examples/lambda-demo |
| make examples/ec2-demo |
Run integration-test:
make integration-test/s3The integration-test installs and compiles the Unison AWS library (generated with smithy-unison and released to Unison Share @f34nk/aws) and runs the S3 demo against a mocked infrastructure.
make integration-test/dynamodbThis integration-test does the above with the DynamoDB demo
Create smithy-build.json:
{
"version": "1.0",
"sources": ["model"],
"maven": {
"dependencies": ["io.smithy.unison:smithy-unison:0.1.0"],
"repositories": [
{
"url": "https://repo1.maven.org/maven2"
},
{
"url": "file://${user.home}/.m2/repository"
}
]
},
"plugins": {
"unison-codegen": {
"service": "com.example#MyClient",
"namespace": "my.client",
"outputDir": "generated"
}
}
}Generate only the operations you need, dramatically reducing code size and compilation time:
{
"plugins": {
"unison-codegen": {
"service": "com.amazonaws.dynamodb#DynamoDB_20120810",
"namespace": "aws.dynamodb",
"operations": [
"CreateTable",
"PutItem",
"GetItem",
"Query",
"DeleteItem"
],
"generateAllOperations": false
}
}
}For example: DynamoDB 9 operations → 3,418 lines (vs ~40K for full model)
Build model:
smithy buildThe generator automatically includes all transitive dependencies (nested types, errors, enums) ensuring type safety and completeness.
Generated files in generated/:
{namespace}_client.u- Client module with types, records, and operations
For AWS services, additional runtime modules are copied:
aws_sigv4.u- AWS Signature V4 request signingaws_xml.u- XML encoding/decoding (REST-XML protocol only)aws_json.u- JSON encoding/decoding with DynamoDB AttributeValue supportaws_json_bridge.u- JSON-HTTP integration with parsing utilities (parseFloat, parseBlob, mapWithException)aws_restjson.u- REST-JSON URL building and parameter handlingaws_http.u- HTTP request/response utilitiesaws_http_bridge.u- Bridge for @unison/http library (enables real HTTP)aws_s3.u- S3-specific URL routing (S3 only)aws_config.u- Shared AWS configuration with type-safe newtypes (Region, Service, HostName, Port, Config, Credentials)aws_credentials.u- Credential provider chain
The generator follows Smithy's recommended DirectedCodegen pattern for extensibility and maintainability.
Reference: Creating a Code Generator
See ARCHITECTURE.md for detailed architecture documentation.
| Component | Description |
|---|---|
UnisonCodegenPlugin |
Main Smithy Build plugin entry point |
UnisonGenerator |
DirectedCodegen implementation for shape-by-shape generation |
UnisonContext |
Centralized access to model, settings, and dependencies |
UnisonSettings |
Immutable configuration from smithy-build.json |
UnisonWriter |
SymbolWriter extension for Unison code output |
UnisonSymbolProvider |
Smithy-to-Unison type mapping |
The generator supports custom integrations via Java SPI (Service Provider Interface):
public class CustomIntegration implements UnisonIntegration {
@Override
public String name() { return "CustomIntegration"; }
@Override
public void preprocessModel(UnisonContext context) {
// Copy runtime modules or perform setup before generation
}
@Override
public void postprocessGeneration(UnisonContext context) {
// Run after generation completes
}
}Register in META-INF/services/io.smithy.unison.codegen.UnisonIntegration:
com.example.CustomIntegration
| Integration | Status | Purpose |
|---|---|---|
SigV4Generator |
✅ | Generates AWS SigV4 request signing code |
RuntimeModuleCopier |
✅ | Copies protocol-specific runtime modules |
| Retry Logic | ✅ | Exponential backoff with jitter in aws_http.u |
Smithy traits are declarative metadata that tell code generators how to generate code, without embedding that logic in the model itself. They separate "what the API looks like" from "how to implement it".
Smithy-unison reads and uses built-in traits via Java's Smithy libraries.
Check out TRAITS.md with all Smithy traits and their support status in smithy-unison.
The generator maps Smithy types to Unison types:
| Smithy Type | Unison Type |
|---|---|
string |
Text |
integer, long |
Int |
float, double |
Float |
boolean |
Boolean |
blob |
Bytes |
timestamp |
Text |
list<T> |
[T] |
map<K, V> |
Map K V |
structure |
Record type |
union |
Sum type |
enum |
Sum type |
Example generated code:
-- Record type from structure
type GetObjectInput = {
bucket : Text,
key : Text,
versionId : Optional Text
}
-- Sum type from enum
type BucketLocationConstraint
= BucketLocationConstraint'UsEast1
| BucketLocationConstraint'UsWest2
| BucketLocationConstraint'EuWest1
-- Error type with toFailure conversion
type NoSuchKey = {
message : Text,
key : Optional Text
}
NoSuchKey.toFailure : NoSuchKey -> IO.Failure
NoSuchKey.toFailure err =
IO.Failure.Failure (typeLink NoSuchKey) err.message (Any err)
-- Operation with exception-based error handling
getObject : aws.config.Config -> GetObjectInput -> '{IO, Exception, Threads} GetObjectOutput
getObject config input =
-- Raises exception on error, returns output directly on success
Use the AWS SDK Generator to generate unison code for any available AWS SDK.
Check out generate-aws-sdk for details.
Apache License 2.0