I was actually looking for a comparison between Orval and Hey-API to share with some colleagues, so this came at the perfect time.
Personally, I think there’s no competition: Hey-API is by far superior to any other OpenAPI client generator I’ve ever tested (and I’ve tried quite a few).
Here are a few thoughts on the points you raised:
"if your project already uses openapi-typescript + openapi-fetch... I do not think you need to migrate immediately"
It's worth noting that, unlike the output generated by Hey-API, this combination doesn't perform any kind of runtime validation on the payload. The client completely trusts the TypeScript types blindly (which, in my opinion, isn't the safest approach, but that's a whole different story...).
"The number of files written to disk becomes a major factor":
That's true, but file I/O bottlenecks can often be mitigated. If you parallelize the execution tasks, you can actually keep the generation speed quite high.
Regarding "Output Size":
We should consider that since a large portion of the output consists of TypeScript types, these are completely stripped out at runtime (e.g., in the final browser bundle). Furthermore, because the generated code repeats the exact same patterns, the gzipped size (which is what the browser actually downloads) doesn't grow linearly with the raw code size. Therefore, a massive raw output size might have a negligible impact on bundle size.
Regarding "Result Union" and Error Models:
A persistent issue that none of the generators I've tested has managed to solve is discriminating between different response schemas. When an endpoint returns a payload that could correspond to multiple success or failure states, these tools don't allow you to easily discriminate between the specific values matching the different schemas defined in the spec. Honestly, this limitation is the unique reason why I ended up writing my own.
I also took a look at your benchmark repository. It’s interesting, although I’d be careful about drawing strong conclusions from older versions since this space moves quite fast.
For example, I’ve already received feedback that newer versions of hey-api have improved generation speed quite a bit, and that the output structure can be customized with options like getFilePath. Things are moving really fast.
The client completely trusts the TypeScript types blindly
Absolutely, TypeScript types alone are not runtime validation. I agree that we still need to think carefully about runtime validation, especially at API boundaries.
Therefore, a massive raw output size might have a negligible impact on bundle size.
I agree with your point that raw output size and actual runtime/bundle impact should be considered separately. Type-only output and gzip can make the practical impact very different from the raw generated size.
And the response schema discrimination issue is also a really interesting point. I didn’t cover it deeply in this article, but I can see why that could become a reason to build a custom solution.
Thanks again, your comment gives me several good points to revisit. 👍
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Thanks for this amazing article!
I was actually looking for a comparison between Orval and Hey-API to share with some colleagues, so this came at the perfect time.
Personally, I think there’s no competition: Hey-API is by far superior to any other OpenAPI client generator I’ve ever tested (and I’ve tried quite a few).
Here are a few thoughts on the points you raised:
It's worth noting that, unlike the output generated by Hey-API, this combination doesn't perform any kind of runtime validation on the payload. The client completely trusts the TypeScript types blindly (which, in my opinion, isn't the safest approach, but that's a whole different story...).
That's true, but file I/O bottlenecks can often be mitigated. If you parallelize the execution tasks, you can actually keep the generation speed quite high.
Regarding "Output Size":
We should consider that since a large portion of the output consists of TypeScript types, these are completely stripped out at runtime (e.g., in the final browser bundle). Furthermore, because the generated code repeats the exact same patterns, the gzipped size (which is what the browser actually downloads) doesn't grow linearly with the raw code size. Therefore, a massive raw output size might have a negligible impact on bundle size.
Regarding "Result Union" and Error Models:
A persistent issue that none of the generators I've tested has managed to solve is discriminating between different response schemas. When an endpoint returns a payload that could correspond to multiple success or failure states, these tools don't allow you to easily discriminate between the specific values matching the different schemas defined in the spec. Honestly, this limitation is the unique reason why I ended up writing my own.
Thanks a lot for the detailed comment! 😺
I also took a look at your benchmark repository. It’s interesting, although I’d be careful about drawing strong conclusions from older versions since this space moves quite fast.
For example, I’ve already received feedback that newer versions of hey-api have improved generation speed quite a bit, and that the output structure can be customized with options like
getFilePath. Things are moving really fast.Absolutely, TypeScript types alone are not runtime validation. I agree that we still need to think carefully about runtime validation, especially at API boundaries.
I agree with your point that raw output size and actual runtime/bundle impact should be considered separately. Type-only output and gzip can make the practical impact very different from the raw generated size.
And the response schema discrimination issue is also a really interesting point. I didn’t cover it deeply in this article, but I can see why that could become a reason to build a custom solution.
Thanks again, your comment gives me several good points to revisit. 👍