Skip to content

Smithy Projects

Filter this guidePick generator option values to hide sections that don't apply.

Smithy is an interface definition language for describing services and the data they exchange. The Smithy project generator creates a project containing a Smithy model.

There are two kinds of Smithy project:

  • Service (--type=service) — a model which defines a service and its operations. This is what the ts#api --framework=smithy generator creates for you alongside a TypeScript implementation.
  • Shape library (--type=shapes) — a model which defines reusable shapes but no service. Connect a shape library to your Smithy projects to share shapes between them, rather than duplicating the definitions in each.
  1. Install the Nx Console VSCode Plugin if you haven't already
  2. Open the Nx Console in VSCode
  3. Click Generate (UI) in the "Common Nx Commands" section
  4. Search for @aws/nx-plugin - smithy#project
  5. Fill in the required parameters
    • name: my-shapes
  6. Click Generate
ParameterTypeDefaultDescription
name Requiredstring-Smithy project name
type service | shapesserviceThe type of Smithy project to create. Choose between service (a model with a service shape, ready for an implementation) and shapes (a shape library of reusable shapes, shared between multiple Smithy projects).
serviceName string-The name of your Smithy service. Uses the supplied name by default. Not applicable to shape libraries.
namespace string-The namespace for the Smithy API. Defaults to your monorepo scope
directory stringpackagesParent directory where the Smithy project is placed.
subDirectory string-The sub directory the Smithy project is placed in. By default this is the project name.
preferInstallDependencies booleantrueWhether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end.
type = shapes
  • Directorymy-shapes
    • Directorysrc
      • main.smithy Your shared shape definitions
    • smithy-build.json Smithy build configuration
    • build.Dockerfile Builds and validates the model
    • project.json Project configuration and build targets

A shape library defines shapes and nothing else:

$version: "2.0"
namespace com.example
structure Customer {
@required
id: String
name: String
email: String
}

Since a shape library has no service, its smithy-build.json configures no code generation — building it validates the model and assembles it into a single JSON model file at dist/<my-shapes>/build/model/model.json.

type = service
  • Directorymy-service
    • Directorysrc
      • main.smithy Your service definition
      • Directoryoperations
        • echo.smithy An example operation
    • smithy-build.json Smithy build configuration, including code generation
    • build.Dockerfile Builds the model, OpenAPI spec and TypeScript Server SDK
    • project.json Project configuration and build targets

A service model defines a service shape and the operations it exposes:

$version: "2.0"
namespace com.example
use aws.protocols#restJson1
@title("MyService")
@restJson1
service MyService {
version: "1.0.0"
operations: [
Echo
]
}

Building a service project generates an OpenAPI specification and a TypeScript Server SDK into dist/<my-service>/build/.

Smithy projects build using Docker, which runs the Smithy CLI to validate your model:

Terminal window
pnpm nx build my-shapes

Building a shape library writes an assembled model to dist/<my-shapes>/build/model/model.json. This single file contains every shape the library defines, along with any it depends on, so a consumer only ever declares the libraries it references directly.

To depend on a shape library from another Smithy project, make three changes to the consuming project:

  1. Smithy projects build inside a container, and the build is given the workspace root as a named build context. Add a COPY to the consuming project’s build.Dockerfile, alongside where its own sources are copied in:

    # Copy project files
    COPY smithy-build.json .
    COPY src src
    COPY --from=workspace dist/packages/my-shapes/build/model/model.json deps/my-shapes.json
  2. Add the copied file to imports in the consuming project’s smithy-build.json:

    {
    "version": "1.0",
    "sources": ["src/"],
    "imports": ["deps/my-shapes.json"],
    ...
    }
  3. Add the library’s build target as a dependency of the consuming project’s compile target in its project.json, so the model exists before the consumer builds:

    {
    "targets": {
    "compile": {
    "dependsOn": ["@my-scope/my-shapes:build"],
    ...
    }
    }
    }

Your model can now reference the library’s shapes with use:

$version: "2.0"
namespace com.example.api
use com.example.shared#Customer
structure GetCustomerOutput {
@required
customer: Customer
}

Shape libraries can depend on other shape libraries the same way. Since each library’s built model already contains its own dependencies, you only need to repeat these steps for the libraries you reference directly. A library reached by more than one path is resolved once — Smithy ignores duplicate but equivalent shape definitions.