1. Design a data abstraction that solves a class of problems.
2. Design a good wire protocol for that abstraction.
3. Better yet, design 2 protocols: one server-to-server and one client-to-server. Federation is the only model that has ever scaled large enough.
4. Implement a simple as possible server. Do not try too hard to make it performant, just very easy to install and very easy to understand. This is the protocol reference implementation.
5. Implement an open source client library, that completely covers the entire data model and the entire wire protocol.
6. Implement another open source client library, in a very different programming language. If this is difficult, you let your knowledge of your favorite language overconstrain the wire protocol. Go back to step 2 and fix it.
7. Implement a command line client on one of those libraries. Again, it must completely cover the entire data model.
8. Implement an ok GUI app.
9. Implement a very high performance highly scalable server. If you are tempted to change the wire protocol to do this, you screwed up.
10. Now, and only now, you can implement a very nice easy to use GUI. At this point, and at this point only, do you bring in any "designers", "UX" people, or anyone who uses Photoshop as working tool.
Of course, for the past 15 years, everyone has been doing this backwards, with disastrous results. It takes huge amounts of wasted CPU and wasted money by the millions and billions to make all the resulting garbage work at all.