Smithy: an interface definition language that pretends the wire format is an implementation detail
Smithy is a protocol-agnostic interface definition language and set of tools for generating clients, servers, and documentation for any programming language.
At a glance
- What is it?
- A Java-built toolchain where a service is modeled as resources, operations and shapes, then code generators turn that model into clients, servers and docs in whatever protocol you like.
- Who is it for?
- Smithy is worth adopting when the same service is consumed by more than one language, or when you want the protocol chosen at generation time rather than baked into the model. The payoff is real: one model file, many targets, and a validation step that catches shape errors before any code exists.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A service is resources, operations and shapes
Smithy's central claim is that you should describe a service once, in terms of its behavior, and let the wire protocol be a later decision. The README opens with exactly that framing: Smithy defines and generates clients, services and documentation for any protocol.
The example model is short enough to read in one go:
$version: "2"
namespace example.weather
service Weather {
version: "2006-03-01"
resources: [City]
operations: [GetCurrentTime]
}A service aggregates resources and operations. A resource carries identifiers and lifecycle bindings, so `read: GetCity` and `list: ListCities` on the `City` resource declare which operations belong to it and how they bind to the resource's identifier. That structure is what lets generators produce something that looks like a typed client rather than a pile of RPC stubs.
The other half of the vocabulary is shapes: the typed structures that operations accept and return. Once you have that, the interesting question becomes what consumes the model.
smithy build and the smithy-build.json entry point
Before anything can be generated, a model has to be assembled, validated and transformed. The README is explicit about the prerequisite: install the Smithy CLI first, then run `smithy build`.
The build is configured by a small JSON file:
{
"version": "1.0",
"sources": ["model"]
}That `sources` entry points at a directory of model files. The README's walkthrough then creates one model and builds it:
$version: "2"
namespace com.example
service ExampleService {
version: "2020-05-27"
}Running `smithy build` on that produces artifacts defined by the same configuration file. The reason this matters is that model assembly is a separate concern from code generation. Transforms, projections and validation all happen at build time, which means a broken shape fails before any generator sees the model, and a model can be validated in CI without generating a line of code.
The README links out to the Building Smithy Models guide for the details on what else goes into that configuration file, and to a separate examples repository for larger models than the twenty lines above.
Sixty modules, most of them AWS and protocol specifics
The repository is a Gradle monorepo, and the tree lists roughly sixty top-level entries. The core is a smaller set: `smithy-model` holds the model objects, `smithy-syntax` the parser, `smithy-build` the build system, `smithy-cli` the command line entry point, and `smithy-codegen-core` the generator abstraction that third-party generators plug into.
Everything else is specialization. The AWS block is the largest cluster: `smithy-aws-traits`, `smithy-aws-iam-traits`, `smithy-aws-apigateway-traits`, `smithy-aws-cloudformation-traits`, `smithy-aws-endpoints`, `smithy-aws-protocol-tests`. If your service is not on AWS, that whole block is scenery.
Protocol work has its own group: `smithy-protocol-traits`, `smithy-protocol-tests` and `smithy-protocol-test-traits`. The OpenAPI bridge is `smithy-openapi` plus `smithy-openapi-traits`, and `smithy-jsonschema` generates JSON Schema. `smithy-docgen` handles documentation, `smithy-diff` compares models, `smithy-linters` and `smithy-rules-engine` enforce policy, and `smithy-jmespath` provides a JMESPath implementation, which Smithy uses for its selector and projection expressions.
GitHub reports the repository language as Java and the license as Apache 2.0, and the README states the same license. That much is consistent.
What the Dockerfile actually builds
The Dockerfile is worth reading because it shows how the toolchain is meant to be shipped, and it contains one detail that has since been overtaken by the release notes.
The build stage starts from a Gradle JDK image, then runs the Gradle wrapper seven times, once per trait artifact: API Gateway traits, CloudFormation traits, IAM traits, AWS traits, MQTT traits, protocol test traits and the validation model. Only after those jars exist does it build `:smithy-cli:runtime`. The ordering is the point: the CLI needs the traits on the classpath before it can validate a model that uses them.
The runtime stage copies the CLI image plus every trait jar into `/smithy/lib/traits/`, then does a two-pass class data sharing setup. It runs `smithy validate` once with `-XX:DumpLoadedClassList` to record which classes load, and again with `-Xshare:dump` and a shared archive file to write the archive itself.
That last step is exactly what release 1.73.0 changed. Its notes say the CLI was updated to use JDK 25 and an ahead-of-time cache instead of AppCDS. The Dockerfile in the tree still specifies a Gradle 7 JDK 17 base image and still writes an AppCDS-style shared archive. Both are in the repository at once, and the release notes are the newer signal, so treat the Dockerfile as lagging rather than authoritative on runtime version.
Releases that show what the toolchain is actually used for
The release history is more informative than the README here, because the README is 2,458 characters long and says almost nothing about how the pieces fit together.
Release 1.74.0, published 2026-09-25, added benchmark models for measuring serialization and deserialization performance, expanded an unstable trait for preview use, and fixed a bug where resource properties and identifiers were not discovered through the output list member of `list` lifecycle operations. That last one is a good illustration of what living in this ecosystem means: `ResourceOperationInputOutput` validation errors on list-only resources were the symptom, and the fix involved `@nestedProperties` on a member targeting a list of structures.
Release 1.73.0, from 2026-08-11, is more revealing about direction. It added a versioned `smithy-agent-skills` artifact containing reviewable Agent Skills, starting with a documentation navigator. It extended `@idempotent` with optional `exists` and `notFound` properties so a client can declare what errors to expect from unexpected resource states. It also extended `@idRef` support to trait code generation and added a cap on selector recursion depth to handle malformed selectors.
The repository's last push was 2026-09-28, one working day after 1.74.0 shipped, and the project is not archived.
Where the README stops and the specification takes over
Smithy has an unusual split between its repository and its documentation, and understanding that split saves a lot of time.
The README is an advertisement with a working twenty-line example. Everything that would actually determine whether Smithy fits your project is on smithy.io: the 2.0 specification under `/2.0/spec/`, the quick start guide, the Smithy CLI installation page, the guide to `smithy-build.json`, and the Javadoc for the Java API. There is also an `awesome-smithy` repository for generators and tools built on top of it, and a Gradle plugin maintained in its own repository.
The practical consequence is that the repository tells you what the toolchain contains and the specification tells you what the language means. If you are deciding between Smithy and writing an OpenAPI document, the comparison you need is about model expressiveness and generator reach, and neither question is answered by a README this short.
One more thing is worth noting about the project's direction. The 1.73.0 addition of packaged Agent Skills, together with the tree containing a `smithy-agent-skills/` directory, suggests the maintainers are treating documentation navigation as a first-class tooling problem rather than a website problem.
Editorial conclusion
Smithy is worth adopting when the same service is consumed by more than one language, or when you want the protocol chosen at generation time rather than baked into the model. The payoff is real: one model file, many targets, and a validation step that catches shape errors before any code exists. The cost is that you are now inside Smithy's own vocabulary, with its versioned spec, its closure rules and its trait system, and the README will not get you out of that. Start with the quick start on smithy.io and the example model in `model/main.smithy`, then look at the module you actually need, whether that is `smithy-cli`, `smithy-build` or the AWS trait jars, before deciding this fits your build.
Frequently asked questions
What does the Smithy IDL let you generate?
Clients, servers and documentation, for any programming language rather than one fixed target. A model describes resources, operations and shapes, and code generators plug into `smithy-codegen-core` to turn that into language-specific clients or service stubs. The repository also includes JSON Schema and documentation generators, plus an OpenAPI bridge in both directions.
Do I need the Smithy CLI to build a model?
Yes. The README marks the Smithy CLI installation as an important prerequisite before building, and the build is driven by `smithy build` with a `smithy-build.json` file naming the model source directories. There is a separate Gradle plugin in its own repository for builds that want model assembly inside an existing Gradle project.
Is Smithy tied to AWS?
The core language is not, but a large share of the repository is AWS-specific: traits for IAM, API Gateway and CloudFormation, an endpoints module, and AWS protocol tests. There are also modules for OpenAPI, JSON Schema, MQTT and JMESPath. A non-AWS service uses a much smaller portion of the tree than the module count suggests.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/smithy-lang-smithy)