I really like the idea of it. My dream has always been to work with "types" first and foremost across any and all languages (yep it is a dream). And little tools like these are really nice to see push that boundary.
One feedback - if you are truly comparing with "other" tools - you should be looking at grpc and protoc plugins. I have used to great effect for things like:
1. Generating wasm bindings for grpc services
2. Generating "data access layer" types so you can choose how a api proto is transformed to a data domain type and vice versa
3. MCP bindings for APIs
4. GraphQL/BFF bindings with multiple services
5. All of the above "across" langauges.
The tooling is fantastic and extensible - if you are ok to start with a proto view of your world - it sounds wierd and like an N+1 problem but once you are used to it it is surprisingly fun (ok we may have different ideas of fun)
Totally - The other really nice thing about Golang "type-system" ecosystem is their native ast in the stdlib. You can do so many amazing things from there. Infact if you pledge your life to Go (which I think I have atleast for now) starting from Go and generating everything outwards is not necessarily a bad strategy.
On this “types first across languages”, I’ve been hacking on something in that vein called Kumi (typed calculation schemas compiled to Ruby/JS). Tiny demo here https://kumi-play-web.fly.dev
Type-first is cool. But I think I'll always aim to avoid gRPC, at least in part because grpc-web was so completely broken. I also have an instinctive aversion to binary formats. YMMV, just my PoV.
I’ve had a lot of success with grpc web. Had to patch a couple of things along the way. My biggest misgiving is thinking having bigints would be a good idea (it is not a good idea). Aside from that though, I’ve been happy with it. What felt broken to you?
+1 Couple of things I really hate about proto - No generics/templates. No composition of services or mixins (you do have composition in messages but that feels very limited). Also the clunkiness around having to declare more things (try a repeated map field or a map of repeated fields).
My comment about protos was just the spec (and was seperating the binary formats as a different concern). But your concerns are pretty valid.
We've been using guts basically since it was published on GitHub (almost a year now), and it's so nice! We have a "custom POST-based JSON-rpc"-style api, so we have request and response bodies defined as Go types, and are generating the whole TS schema from it.
It basically lets you generate typescript types from your Go types. However, it's very customizable - you can post-process the AST. In our case, we have a custom generic Go type that indicates an optional (not nullable) field, and we can easily translate it to optional TS types (e.g. for sparse updates).
All in all, great tool/library, thanks for building it!
Disclaimer: I know a developer at Coder (not the author), who also recommended me guts back then, but am unaffiliated other than that.
If you output Zod you've basically solved Typescript, a Zod schema more or less is a Typescript type and can be explicitly made so with the `infer` capability
I really like the idea of it. My dream has always been to work with "types" first and foremost across any and all languages (yep it is a dream). And little tools like these are really nice to see push that boundary.
One feedback - if you are truly comparing with "other" tools - you should be looking at grpc and protoc plugins. I have used to great effect for things like:
1. Generating wasm bindings for grpc services
2. Generating "data access layer" types so you can choose how a api proto is transformed to a data domain type and vice versa
3. MCP bindings for APIs
4. GraphQL/BFF bindings with multiple services
5. All of the above "across" langauges.
The tooling is fantastic and extensible - if you are ok to start with a proto view of your world - it sounds wierd and like an N+1 problem but once you are used to it it is surprisingly fun (ok we may have different ideas of fun)
I totally agree a proto first approach to your types can pay back in dividends if you need to serialize over different wires.
This project admittedly was developed to solve a specific need in an existing codebase with a lot existing types.
The codebase is also mostly maintain by the backend Golang engineers. Letting them use their native type system increases adoption and buy in.
Totally - The other really nice thing about Golang "type-system" ecosystem is their native ast in the stdlib. You can do so many amazing things from there. Infact if you pledge your life to Go (which I think I have atleast for now) starting from Go and generating everything outwards is not necessarily a bad strategy.
On this “types first across languages”, I’ve been hacking on something in that vein called Kumi (typed calculation schemas compiled to Ruby/JS). Tiny demo here https://kumi-play-web.fly.dev
Hot damn. Id love to hear the origin story of this.
Type-first is cool. But I think I'll always aim to avoid gRPC, at least in part because grpc-web was so completely broken. I also have an instinctive aversion to binary formats. YMMV, just my PoV.
I’ve had a lot of success with grpc web. Had to patch a couple of things along the way. My biggest misgiving is thinking having bigints would be a good idea (it is not a good idea). Aside from that though, I’ve been happy with it. What felt broken to you?
One thing I still struggle to this day is the float/long conversion from json <-> proto. It somehow works and I still untangle the feeling of magic.
+1 Couple of things I really hate about proto - No generics/templates. No composition of services or mixins (you do have composition in messages but that feels very limited). Also the clunkiness around having to declare more things (try a repeated map field or a map of repeated fields).
My comment about protos was just the spec (and was seperating the binary formats as a different concern). But your concerns are pretty valid.
GraphQL has been my holy grail for this. Easy to grok, easy to build types for various languages and keep everything in sync.
GraphQL is awesome if you are a frontend engineer. GraphQL is terrible if you are a backend engineer - https://bessey.dev/blog/2024/05/24/why-im-over-graphql
We've been using guts basically since it was published on GitHub (almost a year now), and it's so nice! We have a "custom POST-based JSON-rpc"-style api, so we have request and response bodies defined as Go types, and are generating the whole TS schema from it.
It basically lets you generate typescript types from your Go types. However, it's very customizable - you can post-process the AST. In our case, we have a custom generic Go type that indicates an optional (not nullable) field, and we can easily translate it to optional TS types (e.g. for sparse updates).
All in all, great tool/library, thanks for building it!
Disclaimer: I know a developer at Coder (not the author), who also recommended me guts back then, but am unaffiliated other than that.
Thrilled to see you got value out of it!
That thing was too big to be called a library. Too big, too thick, too heavy, and too rough, it was more like a large hunk of code.
Why not use OpenAPI for this - https://ashishb.net/programming/openapi/? OpenAPI supports a lot of languages, not just 2.
Nice, this looks interesting.
Somewhat related is a project we worked on within Golang community in Malawi: https://github.com/golang-malawi/geneveev
It supports converting types to Zod schemas and Dart classes. Never got around to TypeScript and would be cool to see if we could add support for guts
If you output Zod you've basically solved Typescript, a Zod schema more or less is a Typescript type and can be explicitly made so with the `infer` capability
There's also https://github.com/tkrajina/typescriptify-golang-structs
Which is used for example in the Go GUI framwork Wails: https://github.com/wailsapp/wails/tree/v2.11.0/v2/internal/b...
Another one: https://github.com/gzuidhof/tygo
(Shoutout to Guido!)
In the same vein: https://typespec.io/