# Install oazapfts as a dependency
npm install oazapfts --save
```

These generators will need an OpenAPI document to work with. A common OpenAPI document used for testing all sorts of OpenAPI tooling is the [Train Travel API](https://github.com/bump-sh-examples/train-travel-api).

Start by downloading the YAML from [https://raw.githubusercontent.com/bump-sh-examples/train-travel-api/refs/heads/main/openapi.yaml](https://raw.githubusercontent.com/bump-sh-examples/train-travel-api/refs/heads/main/openapi.yaml) to the working directory.

```bash
wget https://raw.githubusercontent.com/bump-sh-examples/train-travel-api/refs/heads/main/openapi.yaml
```

## Document validation

Both the OpenAPI Generator and Speakeasy CLI can validate an OpenAPI document to make sure it's valid and well-formed. Oazapfts doesn't offer document validation, so a separate validation step is needed to use it at scale.

To validate `openapi.yaml` using OpenAPI Generator, run the following in the terminal:

```bash
openapi-generator validate -i openapi.yaml
```

The OpenAPI Generator validator returns the following output:

```
Validating spec (openapi.yaml)
No validation issues detected.
```

### Validation using Speakeasy

We'll validate the spec with Speakeasy by running the following in the terminal:

```bash
speakeasy validate openapi -s openapi.yaml
```

The Speakeasy validator returns one warning, and some hints reminding the author to add examples. Each warning or hint includes a detailed, structured error with line numbers to help us fix anything that needs fixing.

Since the Speakeasy validator produced only a warning and hints, we can assume that all our generators will generate SDKs without issues.

Here's how the generators' validation features compare:

<Table
  data={[
    {
      name: "Validates schema",
      speakeasy: "✅",
      openapiGen: "✅",
      oazapfts: "❌",
    },
    {
      name: "Shows line numbers",
      speakeasy: "✅",
      openapiGen: "❌",
      oazapfts: "❌",
    },
    {
      name: "Helpful hints beyond validation",
      speakeasy: "✅",
      openapiGen: "❌",
      oazapfts: "❌",
    },
  ]}
  columns={[
    { key: "name", header: "" },
    { key: "speakeasy", header: "Speakeasy" },
    { key: "openapiGen", header: "OpenAPI Generator" },
    { key: "oazapfts", header: "Oazapfts" },
  ]}
/>

## Generating SDKs

Now that the OpenAPI document has been confirmed valid, it's time to start generating and comparing SDKs. First, create an SDK using Speakeasy, and take a brief look at its structure. Then generate SDKs using the other generators, and compare the generated code to the Speakeasy SDK.

### Generating an SDK using Speakeasy

To create a TypeScript SDK using the Speakeasy CLI, run the following in the terminal:

```bash
speakeasy quickstart
```

It will ask a few questions about the SDK we want to create, including the OpenAPI document (`openapi.yaml`), the name of the SDK (`TrainTravel`), the language/framework which will be TypeScript, and a package name for publishing to NPM (`train-travel-sdk`). Then pick an output directory for the SDK, for example `train-travel-sdk`.

That's it! The Speakeasy CLI generates the SDK, turns it into a Git repository if requested, and creates the following file structure:

```
├── CONTRIBUTING.md
├── FUNCTIONS.md
├── README.md
├── RUNTIMES.md
├── USAGE.md
├── dist
│   ├── commonjs
│   ├── esm
│   └── node_modules
├── docs
│   ├── lib
│   ├── models
│   └── sdks
├── eslint.config.mjs
├── examples
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── README.md
│   └── stationsGetStations.example.ts
├── src
│   ├── core.ts
│   ├── funcs
│   ├── hooks
│   ├── index.ts
│   ├── lib
│   ├── models
│   ├── sdk
│   └── types
└── tsconfig.json
```

At a glance, we can see that Speakeasy creates documentation for each model in the API description. It also creates a full-featured NPM package, with all the Markdown files you'd expect to see in any open-source project. 

Code is split between internal tools and the SDK code, and comes packaged ready for distribution to NPM with support for CommonJS and ES Modules.

We'll start poking around the code to get a feel for how it all works, but first, let's generate SDKs using the other generators.

### Generating SDKs using OpenAPI Generator

OpenAPI Generator is an open-source collection of community-maintained generators. It features generators for a wide variety of client languages, and for some languages, there are multiple generators. TypeScript tops this list of languages with multiple generators, with 11 options to choose from.

The two TypeScript SDK generators from OpenAPI Generator covered here are [typescript-fetch](https://openapi-generator.tech/docs/generators/typescript-fetch/) and [typescript-node](https://openapi-generator.tech/docs/generators/typescript-node/). Both generators are very similar, but the `typescript-fetch` generator creates SDKs that work in both browser and Node.js environments, while the `typescript-node` generator creates SDKs optimized for Node.js environments.

There is no interactive CLI for OpenAPI Generator, so there are no prompts to guide you on the way. Instead you'll do the whole thing with command line arguments:

```bash