Where to put shared structs?

I’m building a client/server app where client and server share the same structs. I’m building it as two separate projects in GitHub but wondering where I should put the shared code. As I see it, my options

  • With the server and import it to the client
  • With the client and import to the server
  • Repeat the code in both projects
  • Put the code in its own project and import it from both

The first option seems the best but I just wanted to check others agreed or could give an argument to doing it a different way.

1 Like

Use the last one.

1 Like

Is it worth it for just a couple of structs?I guess that way is the most flexible though.

It worth. Your struct (also can be just one variable) is a dependency. Any dependency must be packed separately. Is a good practice, is logical and idiomatic.


OK, I’ll do it like that.

For the project structure, I’ve currently got:


Can I put these shared files in:


Or would I be better putting them in a new repo?


I’m still trying to get my head round how to correctly lay things out.

@digininja I think it would be helpful if you could share some context: why are they two separate projects?

Having them be in a single repo is very common, because it eases some pain with compatibility between the two. As you make changes to the code, the client and server can both consume it at the same version and make use of it. I would personally recommend avoiding making this two repos.

1 Like

They are in two repos because that is the way I though it was supposed to be done. I’ve just had a play and didn’t realise I could have:


and have them both build different binaries.

That means I can have this as well:


With all the shared content and all hosted in the same repo.

I’m still trying to get my head around how all of this works and is supposed to be structured.

@digininja what you see some people also do is build one binary, and then use sub-commands to choose what to do:

./project server
# or to run the client
./project client

That way you can ship one artifact that acts as both server and client, and the size likely won’t be much different. Would probably end up being way less since you wouldn’t need two Go binaries.

1 Like

So just have a switch statement in the main function that fires off one or the other? I can do that.

I used to be a developer but now just write small apps so out of touch with the best ways to do things. Slowly learning them though. Thanks for the help.

@digininja That’s one way, yeah. It would take a little more homework I’m sure, but cobra is an awesome library for helping you do that / structure your code in a way to support it:

that looks big and complicated but I’ll have a look, thanks.

I got all this working and now all my code is in the one repo, thanks for the help.

1 Like

Awesome! I’m glad we could help!

@digininja IMHO looks it is good time to look into gRPC. I currently have multiple repositories as well i have separate clients and many servers (services). And all communication is done via gRPC, so all my messages (structs) are defined in single protobufs repository and this github.com/user/stubs/* are shared across all clients and services. Not sure is it overall good or bad in your case, but i think it is worth at least to look at it.

I think it is a bit of overkill in my case, I’ll only have 2-3 messages so 6 structs for request and response at the most. I just wanted to make sure that I got the ideas right for if I have to do it again on a larger scale.

I’ll remember gRPC as well, in case it becomes worth it.

Just stick everything in a single repo.
But put the shared code in a separate package (within this repo) that both the client and server import.

The “monorepo” idea is fairly popular, and has worked out well for me with Go projects. Other articles that discuss the concept:


1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.