Ask HN: Best codebases to study to learn software design?
I’m working on improving my software design skills, and it was recommended that I study existing well designed codebases. What are some publicly accessible codebases you would consider gold standards for software design?
The codebase is not where the design usually lives. It's where the implementation lives. You could imagine a rewrite into another programming language which would preserve the design but completely replace the implementation.
You should practice writing design docs. Don't worry about what the doc is supposed to look like, and definitely don't work off of a template. The most important thing about the doc is that another human could do the implementation if you gave it to them.
The doc can also function as a "proof of consideration". If you choose to do something one way, but there are other possible ways to do it, you can acknowledge the other possible ways, and say why they are worse. By preemptively acknowledging an alternative, you have proved to readers that you considered it.
All a "good" system designer is doing is considering a larger design space than most, and consistently finding good points in the space. Pick a problem, sample points in the design space, tell me why some points are better than others, and write it all down.
Maybe I’m just not good enough at paying attention, but for me it seems like you have to actually run into problems over and over and figure out how to avoid the problems. Then you end up being able to mentally simulate what problems you will run into, and design is basically all about avoiding future problems of various kinds (and balancing tradeoffs about which future problems to avoid and how much effort to put into each, whether you can solve multiple with one design play, etc).
I have this too, I have never been able to "do exercises" or "study a codebase". I need to be making something that I am excited about, then I'll learn, from examples, from wanting to be thorough and correct.
But sometimes I think I'm just not their yet, if I become able to read code like a book and really understand what happens, which often I don't, then perhaps I'll enjoy the process more.
> for me it seems like you have to actually run into problems over and over and figure out how to avoid the problems
This shows how immature the field of software engineering is. Imagine bridges or houses were built like that. Or your surgeon was trained like that.
Over time, we hopefully develop estblished norms, but at the moment, things are too much in flux. Put 5 sw engineers in a room, pose a problem and you will get not just 5 different solution proposals, but there will likely be strong disagreements on which approach is a good one.
"I recognize a good solution when I see it" is just not good enough for a serious engineering discipline.
For me, software design is more comparable to business system and organization design. It’s just that instead of humans executing the processes you design, it’s machines doing it.
I don’t think business system and organization design is approached like bridge design either, is it?
Also, bridges, houses and surgeons can physically kill people if something goes wrong. Software that can physically kill people, such as that in airplanes or missiles, is actually treated quite differently from most software, I think? I don’t have experience in those industries those so I can’t comment on the specifics of how is it different, but my impression is that things are a lot more rigid. Business organization design also can’t directly kill people.
In general, I think that there is a fundamental tension between looseness and flexibility of operations and innovation. If you are super rigorous and have set in stone best practices, it is going to be harder to find new ways of doing things that work better.
I’m not really bothered if people don’t consider software to be a serious engineering discipline. I’m not sure I do either. If someone wants that kind of thing, I’d recommend they go into a different engineering discipline, rather than trying to make software like that.
I generally agree with your point on ease of experimentation, but if we insist on calling it software engineering, then maybe the field needs to adhere to engineering principles, as the GP highlighted.
I believe part of engineering isn’t over-engineering for the task at hand as well. If the costs of a “failure” are low/zero then the right thing can be to move quickly expecting some problems.
I think the field could get better at knowing when costs are low (eg sometimes scalability, cheaper to change a database choice than rebuild a bridge) and where the costs are sometimes very high (eg security).
Bridge building is a lot more conservative when it comes to taking risk in the construction, but that is how we build bridges and lots of bridges collapse because of similar causes:
- Design Deficiencies
- Construction Mistakes
- Maintenance Issues
- etc.
An average of 128 bridges collapse annually in the United States. More than 17,000 bridges in America are considered "fracture critical" (vulnerable to collapse from a single impact).
If they could afford experimenting and have a few bridges collapse before they get it right with no significant negative consequences IMHO it wouldn’t be the worst way to learn.
Maybe even more so for surgeons, being able to experiment and fail in a risk free environment seems like a good thing.
> This shows how immature the field of software engineering is. Imagine bridges or houses were built like that. Or your surgeon was trained like that.
It's not that software engineering is immature, it's just more dynamic.
We are not the surgeon, we write the surgeon. We write a surgeon to fix a broken leg. Once that is done, we don't have to fix another leg. Now we need to reattach a finger. Once that is solved, maybe replace a kidney.
You cannot repetitively train or have strict rules for that, because every time it's something new. You need to have broad knowledge and experience to be able to fight the next unknown challenge. It's unknown because it's never been done before, or it has been done but your competitor will not reveal the details.
Building bridges or being a surgeon sounds very boring to me, since it's always the same (maybe some minor variants). Building software? Very much not the same.
This is pretty much how I've learned up to this point (and will of course continue). Trying to learn from real world code will be a new experience for me. Not sure how valuable it will be but should be fun either way.
That's kinda like saying you can learn to drive by just getting into a car, crashing then thinking about how not to crash it next time.
In reality both things are necessary. The car analogy doesn't hold for road driving because we drive well within the limits, but for racing it really is necessary to know exactly where the limits are. I don't think we should really be treating our profession like a race, though.
But if you don't read it's going to be an incredibly long slow process and a lot of car crashes and mangled gearboxes etc. So I say read, read, and read some more. Even if you don't see the point of it right now your experience will later find a place for it and you won't end up descending a hill for the first time not knowing to shift to a lower gear.
you mention a key point. profession. programmer doesnt really imply professional programmer.
I'd aay if you do it for a living, certain tedious chores must be learned. the best programmers i know (professional) can all read code. they spent many junior years learning to read it, being on code auditing desk.... nowadays idk how the landscape looks, but for all of them they had to review and read code to find bugs before they were allowed to produce code (they all worked at same company ofc... so my view is limited!)
i do feel such discipline is needed. they can always poke holes on my code no matter how many holes i plug :) - i am semi professional. i write code for work, but not production code. (experimental). i never learned to audit code and feel that makes it impossible for me to truly create production grade code
>That's kinda like saying you can learn to drive by just getting into a car, crashing then thinking about how not to crash it next time.
That would be a perfectly valid way of learning to drive if crashing had no danger or destruction and you could instantly reset the car every time. Software is a special case of engineering where the cost of failure is extremely low, so trial and error is generally the fastest way to get going with actually doing something.
My immediate reaction to this question is: "your team's". Nothing will teach you more about how to design software then really understanding why good and bad solutions were adapted to solve a certain real problem.
Software exists precisely because there is still a messy layer connecting user requirements to actions on a computer. If there was not messiness then we could just automate it all. Approaching software from some sort of Platonic ideal of what software should be will frequently lead to bad decisions on it's own.
When you start to see how certain pressures lead to certain paths you learn to recognize the wrong decisions that are often good at the time, and avoid them. At the same time, you need to learn to develop methods that work quickly and effectively. By far the biggest real challenge in real world software is time constraints. This is almost never discussed in theoretical views of software, but the truth is you're always going to be writing code under pressure to ship. You will come across situations where you do not have time to do what you want to do or think is best.
Good software is software that runs and solves the user need, but you will come to realize that there are design solutions that will make successfully running happen more often. The best way to find these is to study the real software you're writing.
Then it still matters a lot what kind of codebase he is working on. A web project is differently structured and done than the codebase for a embedded operating system. There are differend standards and practices in the industry.
I learned a lot by just stepping through the code with the debugger of libaries I used. That brought more practical insight while learning about design patterns etc. In the end, it is all about patterns. Finding the right pattern for a given problem.
I would be interested in recommendations for those who have a poor example or no examples
In my case, I'm a junior engineer that has recently been given more responsibility designing aspects of our product. I'm just trying to learn all I can so my designs will be good!
I haven't considered time to implement as a metric for evaluating design, but it makes a lot of sense.
I definitely learn so much from my team's codebase. Most of what I learn is either from the good designs I see in there or from my googling trying to fix the not so good parts.
These are several years old at this point, but many open source project leaders contributed to the series "The Architecture of Open Source Applications", which is free to read online: https://aosabook.org/en/index.html
My experience (30 years in software, 25 in practicing architecture, MIT system architecture masters) tells me there is no such thing as abstractly “good” design. There are designs with negative consequences for sure, but “good” depends on the context: what are you building, safety/security requirements etc. Probably most importantly on the implementation team and it’s structure. A team of juniors will butcher your intricate design and Conway’s Law makes your software reflect the team.
It's about having most compromises be Not Totally Stupid and have the worst ones only be locally stupid. There is a big universe out there of compromises that fulfill those criteria. As you imply, a lot of the time it's more about constantly fighting for Less-Bad-and-avoiding-Dumb than about architecture as such.
Yeah, as I've been learning more about software design, it's become pretty clear there is no silver bullet. It would be nice though. I find it a bit overwhelming to try to find the best solution for a problem when there are so many different architectures and programming paradigms.
That being said, taking into account the requirements does eliminate quite a few of the options. Right now, I work on safety-critical embedded systems which requires us to make some decisions that would most likely be way different in other environments.
* "well designed": What was the objectives and ideas...
* "codebases": How well that was implemented
They are a lot of lofty claims saying how this or that is "fast, secure, etc" but don't end like that in the actual implementation.
But most of the time, that could be seen in the "design claims" already! Good design is not just full of adjectives and nice sounding goals, but the concrete considerations, what was the trade-offs, false-starts, and reasons behind the decisions.
You can see some examples reading about the design of Erlang, early pascal, most RDBMS, etc.
So, you first mid/long term goal is to learn to distinguish what good design actual look like.
then, in relation with codebases then to be kinda easier: It actually follow the design?
A good example is the 'std' library of Rust. It has a lot of lofty claims about security and such things that could sound alarms, but then you dive in the code of it and see is there A LOT of care about it, and a lot of docs comments discussing this stuff and then the code match.
P.D: The "std" or equivalent of the lang is one of the most important codebases you need to learn and study, and the MAJOR way to judge how truly good is it.
Trying to learn software design by looking at code is kind of like trying to learn about architecture looking at the bricks that make up a building.
To learn about design you need a wider perspective. You can theoretically learn it from code but it won’t be most effective. Look at great documentation and literature about design instead.
Yeah, I guess without the context I wouldn't really understand why it was designed that way. Or know what situations a design like that would be good for.
Is there any documentation or literature that has helped you?
I think there is value in groking entire code bases. It's not just about whether or not they are well designed though. It is an important skill to be able to analyze and see the big picture of how things work together in large systems. For me it often involves drawing diagrams (sometimes UML) to map things out. Being able to view systems in this way is a pre-requisite to intentionally designing your own systems at this level. And yes, once you can work at this level you can learn from good designs, but also see problems with bad ones.
EDIT: and to answer your question, if you're working on something that is "like X but different" then read the source code for X. You could also look at source code for software that you use from day to day: software where you already know what it does. For example, if you're in web, maybe the web framework, or web server, if you write python, maybe a core library that you use, or maybe the python interpreter, or if you use vscode ..., if you use android ..., you get the idea. At the start I would suggest smaller programs, and programs where you already know the domain (e.g. cpython might not be the best place to start if you never implemented an interpreter before, you may spend more time learning about interpreters than the design of this one, still a good thing to learn of course.)
Well maybe I'll take some time to learn about email servers then. I use email everyday so I suppose it'll be good to know a little more about how it works.
While studying well-designed codebases is incredibly valuable, there's an important "tip of the iceberg" effect to consider: much of good software design lives in the "negative space" - what's deliberately not there.
The decisions to exclude complexity, avoid premature abstractions, or reject certain patterns are often just as valuable as the code you can see. But when you're studying a codebase, you're essentially seeing the final edit without the editor's notes - all the architectural reasoning that shaped those choices is invisible.
This is why I've started maintaining Architectural Decision Records (ADRs) in my projects. These document the "why" behind significant technical choices, including the alternatives we considered and rejected. They're like technical blog posts explaining the complex decisions that led to the clean, simple code you see.
ADRs serve as pointers not just for future human maintainers, but also for AI tools when you're using them to help with coding. They provide readable context about architectural constraints and compromises - "we've agreed not to do X because of Y, so please adhere to Z instead." This makes AI assistance much more effective at respecting your design decisions rather than suggesting patterns you've deliberately avoided.
When studying codebases for design patterns, I'd recommend looking for projects that also maintain ADRs, design docs, or similar decision artifacts. The combination of clean code plus the architectural reasoning behind it - especially the restraint decisions - provides a much richer learning experience.
Some projects with good documentation of their design decisions include Rust's RFCs, Python's PEPs, or any project following the ADR pattern. Often the reasoning about what not to build is more instructive than the implementation itself.
Oooh I like that idea. I may steal it. I'll be on the lookout for documents like that. It'll be interesting to see what patterns/designs were avoided. There are so many ways to accomplish the same thing it might be nice to set some limits.
The codebases I learned from the most are Git, Postgres, CPython. Not saying they are perfect designs, but they are well maintained, solve hard problems, have seen many years of evolution, and are very easy to get your hands on.
Top 5 codebases for changing my mind about things:
Wietse Venema's Postfix mail server. Taught me tons about security posture, the architecture i'd describe as microservices before microservices was a thing, but contrary to the modern take on microservices (it's mostly a tool for decomposing work across large semi-isolated groups) this was primarily about security and simplicity.
Spring framework - this opened my eyes to ways of working that i hadn't really thought enough about before, the developers on that project have a culture of deeply considering the needs of their users (who are java developers often in an enterprise environment).
Git - the thing i like about the git code base is that once you've covered the objects database (e.g. blobs, trees and commits) and the implementation of refs, everything else just feels like additional incremental features. With those core concepts, everything else is kinda harmoniously built on top.
Varnish by Poul Henning-Kamp is another one - feels like he went to great lengths to make that code base a teaching tool despite the fact it's also a top tier reverse proxy.
Last one isn't a code base - but it will help with software design in the large; studying how the lieutenants model works in the linux kernel.
Thinking about my answers, i think i've highlighted something subtly different than "well designed codebases" it's more a list of codebases that left a notable long lasting impression on me because of design decisions they made.
study modern code bases of language you want to learn, and look first at their history to see if they are mature, came from a company, academics etc.
you should not only study 'good' code... how will you know what is bad code?
study code that does similar things to what u want (client/server/game/ai/datacrunching etc.)
and study lot of it..different qualities, ages, and sources
I'm definitely going to do that. I asked because I wanted to start off with some that I'd knew would be well designed. However, it would probably be more interesting to see a wide variety of quality than just the good ones.
Or maybe open source projects are all usually well designed. I haven't looked at many in depth. The only one I've really looked into was Clang to try to figure out why clang format ignored my style rules when styling files of certain names. (Turns out there is a list of file names that automatically are considered Objective-C rather than C++)
One thing to keep in mind is that what was well-designed 30, 20 or 10 years ago may not be considered such now. Hardware changes and so do the design decisions involving performance.
For example, if you are looking at C++ networking libraries, learning from ACE or even Asio may not be the best idea - better look at "thread per core, share nothing" Seastar[0].
Another thing is that it may be better to read design docs, not the code. For example, the rationale for the mold linker design[1].
Your own. Everyone else's is trash. Never understand someone else's code-- the whole point is that there should be just a handful of functions of yours I can call, and shouldn't ever care to see how the sausage is made. Otherwise, your abstraction sucks
I agree that the internals of my code should be abstracted away from my users. But don't I still want the internals to be well designed so they are maintainable and extendable?
Are there any books or websites you'd recommend I read to learn more about design instead? I 100% need to learn by doing, but wouldn't it also be good to learn what has already been discovered so I don't have to reinvent the wheel? Or is it best to discover good design on your own?
You should practice writing design docs. Don't worry about what the doc is supposed to look like, and definitely don't work off of a template. The most important thing about the doc is that another human could do the implementation if you gave it to them.
The doc can also function as a "proof of consideration". If you choose to do something one way, but there are other possible ways to do it, you can acknowledge the other possible ways, and say why they are worse. By preemptively acknowledging an alternative, you have proved to readers that you considered it.
All a "good" system designer is doing is considering a larger design space than most, and consistently finding good points in the space. Pick a problem, sample points in the design space, tell me why some points are better than others, and write it all down.
But sometimes I think I'm just not their yet, if I become able to read code like a book and really understand what happens, which often I don't, then perhaps I'll enjoy the process more.
This shows how immature the field of software engineering is. Imagine bridges or houses were built like that. Or your surgeon was trained like that.
Over time, we hopefully develop estblished norms, but at the moment, things are too much in flux. Put 5 sw engineers in a room, pose a problem and you will get not just 5 different solution proposals, but there will likely be strong disagreements on which approach is a good one.
"I recognize a good solution when I see it" is just not good enough for a serious engineering discipline.
I don’t think business system and organization design is approached like bridge design either, is it?
Also, bridges, houses and surgeons can physically kill people if something goes wrong. Software that can physically kill people, such as that in airplanes or missiles, is actually treated quite differently from most software, I think? I don’t have experience in those industries those so I can’t comment on the specifics of how is it different, but my impression is that things are a lot more rigid. Business organization design also can’t directly kill people.
In general, I think that there is a fundamental tension between looseness and flexibility of operations and innovation. If you are super rigorous and have set in stone best practices, it is going to be harder to find new ways of doing things that work better.
I’m not really bothered if people don’t consider software to be a serious engineering discipline. I’m not sure I do either. If someone wants that kind of thing, I’d recommend they go into a different engineering discipline, rather than trying to make software like that.
While I don't disagree with you in general, this does feel a bit off.
By that logic you can call the field of music immature, and all of the arts. I think the difference is that its easy to experiment without high costs.
I genuinely think that if building bridges was cheap and quick, the fastest way to learn was to try...
I think the field could get better at knowing when costs are low (eg sometimes scalability, cheaper to change a database choice than rebuild a bridge) and where the costs are sometimes very high (eg security).
Engineering applies to looking at a design and proving something about it.
Bridge building is a lot more conservative when it comes to taking risk in the construction, but that is how we build bridges and lots of bridges collapse because of similar causes:
An average of 128 bridges collapse annually in the United States. More than 17,000 bridges in America are considered "fracture critical" (vulnerable to collapse from a single impact).If they could afford experimenting and have a few bridges collapse before they get it right with no significant negative consequences IMHO it wouldn’t be the worst way to learn.
Maybe even more so for surgeons, being able to experiment and fail in a risk free environment seems like a good thing.
It's not that software engineering is immature, it's just more dynamic.
We are not the surgeon, we write the surgeon. We write a surgeon to fix a broken leg. Once that is done, we don't have to fix another leg. Now we need to reattach a finger. Once that is solved, maybe replace a kidney.
You cannot repetitively train or have strict rules for that, because every time it's something new. You need to have broad knowledge and experience to be able to fight the next unknown challenge. It's unknown because it's never been done before, or it has been done but your competitor will not reveal the details.
Building bridges or being a surgeon sounds very boring to me, since it's always the same (maybe some minor variants). Building software? Very much not the same.
In reality both things are necessary. The car analogy doesn't hold for road driving because we drive well within the limits, but for racing it really is necessary to know exactly where the limits are. I don't think we should really be treating our profession like a race, though.
But if you don't read it's going to be an incredibly long slow process and a lot of car crashes and mangled gearboxes etc. So I say read, read, and read some more. Even if you don't see the point of it right now your experience will later find a place for it and you won't end up descending a hill for the first time not knowing to shift to a lower gear.
I'd aay if you do it for a living, certain tedious chores must be learned. the best programmers i know (professional) can all read code. they spent many junior years learning to read it, being on code auditing desk.... nowadays idk how the landscape looks, but for all of them they had to review and read code to find bugs before they were allowed to produce code (they all worked at same company ofc... so my view is limited!)
i do feel such discipline is needed. they can always poke holes on my code no matter how many holes i plug :) - i am semi professional. i write code for work, but not production code. (experimental). i never learned to audit code and feel that makes it impossible for me to truly create production grade code
That would be a perfectly valid way of learning to drive if crashing had no danger or destruction and you could instantly reset the car every time. Software is a special case of engineering where the cost of failure is extremely low, so trial and error is generally the fastest way to get going with actually doing something.
Software exists precisely because there is still a messy layer connecting user requirements to actions on a computer. If there was not messiness then we could just automate it all. Approaching software from some sort of Platonic ideal of what software should be will frequently lead to bad decisions on it's own.
When you start to see how certain pressures lead to certain paths you learn to recognize the wrong decisions that are often good at the time, and avoid them. At the same time, you need to learn to develop methods that work quickly and effectively. By far the biggest real challenge in real world software is time constraints. This is almost never discussed in theoretical views of software, but the truth is you're always going to be writing code under pressure to ship. You will come across situations where you do not have time to do what you want to do or think is best.
Good software is software that runs and solves the user need, but you will come to realize that there are design solutions that will make successfully running happen more often. The best way to find these is to study the real software you're writing.
What if the question is asked by a college student?
I learned a lot by just stepping through the code with the debugger of libaries I used. That brought more practical insight while learning about design patterns etc. In the end, it is all about patterns. Finding the right pattern for a given problem.
In my case, I'm a junior engineer that has recently been given more responsibility designing aspects of our product. I'm just trying to learn all I can so my designs will be good!
I definitely learn so much from my team's codebase. Most of what I learn is either from the good designs I see in there or from my googling trying to fix the not so good parts.
* https://news.ycombinator.com/item?id=36370684
* https://news.ycombinator.com/item?id=30752540
* https://news.ycombinator.com/item?id=9896369 (Python specific)
I think there was another one with a similar name but I can't think of it's name.
0: https://www.spinellis.gr/codereading/, check the TOC https://www.spinellis.gr/codereading/toc.html
That being said, taking into account the requirements does eliminate quite a few of the options. Right now, I work on safety-critical embedded systems which requires us to make some decisions that would most likely be way different in other environments.
* "well designed": What was the objectives and ideas...
* "codebases": How well that was implemented
They are a lot of lofty claims saying how this or that is "fast, secure, etc" but don't end like that in the actual implementation.
But most of the time, that could be seen in the "design claims" already! Good design is not just full of adjectives and nice sounding goals, but the concrete considerations, what was the trade-offs, false-starts, and reasons behind the decisions.
You can see some examples reading about the design of Erlang, early pascal, most RDBMS, etc.
So, you first mid/long term goal is to learn to distinguish what good design actual look like.
then, in relation with codebases then to be kinda easier: It actually follow the design?
A good example is the 'std' library of Rust. It has a lot of lofty claims about security and such things that could sound alarms, but then you dive in the code of it and see is there A LOT of care about it, and a lot of docs comments discussing this stuff and then the code match.
P.D: The "std" or equivalent of the lang is one of the most important codebases you need to learn and study, and the MAJOR way to judge how truly good is it.
https://medium.com/@012parth/what-source-code-is-worth-study...
https://aosabook.org/en/index.html
Maybe that would be a good start. You can then pick a project to dive in.
As a more specific tip, I've done some hacks in Nginx long time ago and found it quite nice.
To learn about design you need a wider perspective. You can theoretically learn it from code but it won’t be most effective. Look at great documentation and literature about design instead.
Is there any documentation or literature that has helped you?
EDIT: and to answer your question, if you're working on something that is "like X but different" then read the source code for X. You could also look at source code for software that you use from day to day: software where you already know what it does. For example, if you're in web, maybe the web framework, or web server, if you write python, maybe a core library that you use, or maybe the python interpreter, or if you use vscode ..., if you use android ..., you get the idea. At the start I would suggest smaller programs, and programs where you already know the domain (e.g. cpython might not be the best place to start if you never implemented an interpreter before, you may spend more time learning about interpreters than the design of this one, still a good thing to learn of course.)
https://www.postfix.org/OVERVIEW.html
You might need to know a bit about how email servers work to appreciate it though.
The decisions to exclude complexity, avoid premature abstractions, or reject certain patterns are often just as valuable as the code you can see. But when you're studying a codebase, you're essentially seeing the final edit without the editor's notes - all the architectural reasoning that shaped those choices is invisible.
This is why I've started maintaining Architectural Decision Records (ADRs) in my projects. These document the "why" behind significant technical choices, including the alternatives we considered and rejected. They're like technical blog posts explaining the complex decisions that led to the clean, simple code you see.
ADRs serve as pointers not just for future human maintainers, but also for AI tools when you're using them to help with coding. They provide readable context about architectural constraints and compromises - "we've agreed not to do X because of Y, so please adhere to Z instead." This makes AI assistance much more effective at respecting your design decisions rather than suggesting patterns you've deliberately avoided.
When studying codebases for design patterns, I'd recommend looking for projects that also maintain ADRs, design docs, or similar decision artifacts. The combination of clean code plus the architectural reasoning behind it - especially the restraint decisions - provides a much richer learning experience.
Some projects with good documentation of their design decisions include Rust's RFCs, Python's PEPs, or any project following the ADR pattern. Often the reasoning about what not to build is more instructive than the implementation itself.
The codebases I learned from the most are Git, Postgres, CPython. Not saying they are perfect designs, but they are well maintained, solve hard problems, have seen many years of evolution, and are very easy to get your hands on.
https://www.instagram.com/reel/C2x4Ge5RtNC/
Top 5 codebases for changing my mind about things:
Wietse Venema's Postfix mail server. Taught me tons about security posture, the architecture i'd describe as microservices before microservices was a thing, but contrary to the modern take on microservices (it's mostly a tool for decomposing work across large semi-isolated groups) this was primarily about security and simplicity.
Spring framework - this opened my eyes to ways of working that i hadn't really thought enough about before, the developers on that project have a culture of deeply considering the needs of their users (who are java developers often in an enterprise environment).
Git - the thing i like about the git code base is that once you've covered the objects database (e.g. blobs, trees and commits) and the implementation of refs, everything else just feels like additional incremental features. With those core concepts, everything else is kinda harmoniously built on top.
Varnish by Poul Henning-Kamp is another one - feels like he went to great lengths to make that code base a teaching tool despite the fact it's also a top tier reverse proxy.
Last one isn't a code base - but it will help with software design in the large; studying how the lieutenants model works in the linux kernel.
Thinking about my answers, i think i've highlighted something subtly different than "well designed codebases" it's more a list of codebases that left a notable long lasting impression on me because of design decisions they made.
you should not only study 'good' code... how will you know what is bad code?
study code that does similar things to what u want (client/server/game/ai/datacrunching etc.) and study lot of it..different qualities, ages, and sources
Or maybe open source projects are all usually well designed. I haven't looked at many in depth. The only one I've really looked into was Clang to try to figure out why clang format ignored my style rules when styling files of certain names. (Turns out there is a list of file names that automatically are considered Objective-C rather than C++)
Yes, all open-source projects are well designed with documentation and to-dos, otherwise open-source contribution becomes difficult.
One thing to keep in mind is that what was well-designed 30, 20 or 10 years ago may not be considered such now. Hardware changes and so do the design decisions involving performance.
For example, if you are looking at C++ networking libraries, learning from ACE or even Asio may not be the best idea - better look at "thread per core, share nothing" Seastar[0].
Another thing is that it may be better to read design docs, not the code. For example, the rationale for the mold linker design[1].
[0] https://docs.seastar.io/master/tutorial.html#asynchronous-pr...
[1] https://github.com/rui314/mold/blob/main/docs/design.md
A code base with excellent design will show you the end state but not how it got there but probably not the trade offs and decisions involved.
Practicing refactoring on subpar code bases and dealing with the consequences of your decisions is a better way to improve.
I read design patterns books when i was younger but in retrospect that was a hindrance more than a help.