I've never experienced a situation where a software design document meaningfully improved the overall process. At best, it helps to keep the business in sync at the expense of a much longer delivery timetable. Even high level software delivery contracts never seem to stay on rails for very long.
It is often faster to just build the damn thing and see where it lands. Software is not like a nuclear power plant or offshore oil platform. You do not need to prove a whole lot of things in advance of construction. No one actually has to give you permission to do anything. You can email a link of a vertical slice prototype to the business whenever you feel like it. That can be the "design document".
I'll admit a lot of bias because I think design docs are extremely useful, but I find that when people hate design docs, it's almost always for one of two reasons:
1. The developer has worked on teams where design docs are viewed as a pointless requirement, so authors treat them as a pointless requirement and write bad docs and their teammates view them as pointless so they don't bother giving useful feedback.
2. The developer does not like other people questioning their engineering choices, and they know that it's harder for their teammates to push back on finished code than a design doc. Investing in the implementation before design changes the calculus to bias in favor of whatever's already implemented rather than what would have been the ideal implementation. Plus, it's harder for the team to review design decisions of 10k LOC than a 5-page design doc.
It sounds like you’re defining design as UI/UX design. I think most people include (prioritize, even) things like system architecture, performance bounds, etc.
Software is in nuclear plants, cars, oil platforms, pacemakers, everywhere. If one is writing more ‘disposable’ stuff like flashlight apps for smartphones, then sure, as you say. Others are writing serious stuff, and design docs are invaluable.
> No one actually has to give you permission to do anything.
For now, in the current context (with ai), it seems like a non-ignorable portion of society now wants to limit what kind of code people can write, Ai is apparently sufficiently like nuclear science that regulation may come to the act of producing code.
You have successfully optimized for fast, but you have not optimized for quality, extensibility, customer experience, or maintainability. Fast can be a great thing to optimize for, but there are many other situations where other optimizations are preferable.
Welcome both of you to the agile vs waterfall arguments of 25+ years ago. :)
The agilists I think ended up having pretty good answers for finding a sweet spot between small iterations that maintained quality while minimizing Big Design Upfront to prevent spending a lot of time preplanning the software, allowing a well functioning agile team to maintain reasonably high quality, extensibility, maintainability and satisfaction of actual customer needs while keeping velocity high and not getting bogged down in design heavy tar pits which were ended up not fully anticipating problems encountered during actual execution.
If that doesn't sound like a buzzword filled sentence I never expected to come out my mouth... But. The bottom line is: if you can keep your execution goals small and focused enough, you can iterate quickly towards a design with better information than you would have if you were to do a design study because you'll be better informed by the actual needs of the execution process than by what you _think_ the execution process will require at design time.
Author here. Happy to take any feedback about this post.
I learned to write design docs at Microsoft and Google, and I thought they both had good culture around docs that hasn't percolated out as well as other engineering practices at those orgs. I haven't seen a thorough explanation of how to write design docs, so this is my attempt to externalize what I've learned about writing them.
Isn't much of this made redundant by being part of an existing system? Also, this level of detail is a recipe for being outdated once the issues, compromises and compromises starts coming in
Some of the items in your document seem more like non-functional requirements that I would expect to find in a specification, not a design document,e.g., security, privacy, legal.
It reads more like a CONOPS or a software architecture document, but its not detailed enough from a high level perspective, and too detailed at a low level perspective (ie. it has implementation details in a few places you would expect in a higher level design doc).
In that light, I'm not sure who the audience would be in a corporate environment. Is it for architects, other developers, or yourself?
Some items in your doc seem more like non-functional requirements that I would expect to see in a specification, not a design document: e.g., security, privacy, legal.
No feedback on the design doc, except to say it's a good template and very helpful for someone who hasn't worked in a world where design docs have been critical. But can I say we use tinybeans and have a similar complaint (and others), and we would happily jump ship if there was an alternative like that laid out in your example.
I have worked on DO-178C (aerospace) and IEC 62304 (medical device) software design documents and they are much narrower in scope.
OP's design document is comprehensive enough to cover much of ground of the full documentation package for regulated software submissions. Basically all that's left is tracing requirements to design to verification method to verification result.
Really nice read. I'll add that it's effective to scope design docs up and down as needed, both in terms of how big your project is and how big your company is. A 50-person startup doesn't need a full design doc with multiple approvers. But a one-pager explaining what you're doing and having some documentation is really helpful even with an engineering team of 5. I'll also still write design docs for code changes that only touch a handful of files, if I feel it's important enough. The process of writing in a concise and precise way for other people to consume also has the positive side effect of making things more clear for yourself, too.
> Interfaces section
Only real criticism I have here, is I would not include any code in a design doc, unless it is really really vitally important. I've seen a lot of design docs (especially in the LLM age, written by more junior staff) which are effectively just an English summary of code. The point of a design doc is (generally) not to explain that you're going to have a WidgetManager and WidgetFactory class and what specific properties and methods they have, it's to explain how the widget creation workflow works and maybe you have the WidgetManager/WidgetFactory in an architecture diagram. As a general rule, if you're starting to include actual code, you've gone too low-level, IMO.
> Not all design decisions are equally important. Some choices are more permanent than others.
At AWS one of the corporate culture memes was calling a decision either a "one-way door" or "two-way door". Just asking yourself the question, if we had to walk this back, is it truly irreversible or just an inconvenience? Turns out most day-to-day decisions are two-way doors, particularly engineering ones. Even if the choice made is wrong and a bunch of work needs to be done to switch back, it's still preferable to what a lot of companies end up in, which is decision paralysis where every change needs approval from multiple committees, resulting in months or years before work can start. Note that this doesn't meaningfully increase the odds the decisions made are the right ones; it just delays the implementation and diffuses responsibility if the wrong decision was made.
> A from-scratch rewrite would never work, and even if you manage to write new code in Rails, you’re still maintaining code in two wildly different languages.
Orthogonal to the article, but this line of thinking (including the link to the classic 2000 "Things You Should Never Do, Part I" article[0]) may be worth reviewing in the post-LLM world; for all their flaws, LLMs are spectacular at language-to-language translation, and we already have one major project released[1] that shows porting a relatively large and mature project from one language to another is possible. Not to say that it's the best use of your time, or that you shouldn't do your due diligence and pick the right language up front, or even that the original 2000 article was about a language-to-language rewrite (the Netscape rewrite was an architectural redesign).
Thanks for reading and for the thoughtful feedback!
> Only real criticism I have here, is I would not include any code in a design doc, unless it is really really vitally important.;
Yeah, that's fair. If I were setting guidelines for a large org, I'd maybe discourage code snippets in design docs, as it's hard to know when is too much. At my last company, the dev team was just 3-4 people, and I found it helpful to have little snippets in design docs especially when we're talking about semantics of a new library or how to migrate existing code to a new system.
> Orthogonal to the article, but this line of thinking (including the link to the classic 2000 "Things You Should Never Do, Part I" article[0]) may be worth reviewing in the post-LLM world; for all their flaws, LLMs are spectacular at language-to-language translation, and we already have one major project released[1] that shows porting a relatively large and mature project from one language to another is possible.
Yeah, I agree this could change with LLMs, but I think Joel is still correct up to today. Bun is an interesting case because it's friendliest possible conditions for an LLM rewrite (self-contained inputs and outputs, easy to test old implementation and new implementation side by side, huge test corpus w/ third-party tests). I haven't followed it closely, but it seems like the jury's still kind of out as to whether the rewrite was a good idea.
Claude, write a skill to create design docs as per this blog post /s
In all seriousness a big chunk of my work is reviewing docs and 100% of the design docs I read these days are generated and there is a lot of slop. I have to parse them with AI to make sense of them, contributing to the problem. I wish people would follow a sensible set of rules like this one.
Did anyone have any solution to this dread? Or cracked the code on how to write docs that have other agents as their primary audience?
I've never experienced a situation where a software design document meaningfully improved the overall process. At best, it helps to keep the business in sync at the expense of a much longer delivery timetable. Even high level software delivery contracts never seem to stay on rails for very long.
It is often faster to just build the damn thing and see where it lands. Software is not like a nuclear power plant or offshore oil platform. You do not need to prove a whole lot of things in advance of construction. No one actually has to give you permission to do anything. You can email a link of a vertical slice prototype to the business whenever you feel like it. That can be the "design document".
OP here!
I'll admit a lot of bias because I think design docs are extremely useful, but I find that when people hate design docs, it's almost always for one of two reasons:
1. The developer has worked on teams where design docs are viewed as a pointless requirement, so authors treat them as a pointless requirement and write bad docs and their teammates view them as pointless so they don't bother giving useful feedback.
2. The developer does not like other people questioning their engineering choices, and they know that it's harder for their teammates to push back on finished code than a design doc. Investing in the implementation before design changes the calculus to bias in favor of whatever's already implemented rather than what would have been the ideal implementation. Plus, it's harder for the team to review design decisions of 10k LOC than a 5-page design doc.
It sounds like you’re defining design as UI/UX design. I think most people include (prioritize, even) things like system architecture, performance bounds, etc.
Software is in nuclear plants, cars, oil platforms, pacemakers, everywhere. If one is writing more ‘disposable’ stuff like flashlight apps for smartphones, then sure, as you say. Others are writing serious stuff, and design docs are invaluable.
The software development realm is bigger than web programming.
> No one actually has to give you permission to do anything.
For now, in the current context (with ai), it seems like a non-ignorable portion of society now wants to limit what kind of code people can write, Ai is apparently sufficiently like nuclear science that regulation may come to the act of producing code.
You have successfully optimized for fast, but you have not optimized for quality, extensibility, customer experience, or maintainability. Fast can be a great thing to optimize for, but there are many other situations where other optimizations are preferable.
Welcome both of you to the agile vs waterfall arguments of 25+ years ago. :)
The agilists I think ended up having pretty good answers for finding a sweet spot between small iterations that maintained quality while minimizing Big Design Upfront to prevent spending a lot of time preplanning the software, allowing a well functioning agile team to maintain reasonably high quality, extensibility, maintainability and satisfaction of actual customer needs while keeping velocity high and not getting bogged down in design heavy tar pits which were ended up not fully anticipating problems encountered during actual execution.
If that doesn't sound like a buzzword filled sentence I never expected to come out my mouth... But. The bottom line is: if you can keep your execution goals small and focused enough, you can iterate quickly towards a design with better information than you would have if you were to do a design study because you'll be better informed by the actual needs of the execution process than by what you _think_ the execution process will require at design time.
> you have not optimized for quality, extensibility, customer experience, or maintainability
A ”software design” document does not optimize for either of those.
[delayed]
Author here. Happy to take any feedback about this post.
I learned to write design docs at Microsoft and Google, and I thought they both had good culture around docs that hasn't percolated out as well as other engineering practices at those orgs. I haven't seen a thorough explanation of how to write design docs, so this is my attempt to externalize what I've learned about writing them.
How are design docs changing in the agentic age?
Isn't much of this made redundant by being part of an existing system? Also, this level of detail is a recipe for being outdated once the issues, compromises and compromises starts coming in
Some of the items in your document seem more like non-functional requirements that I would expect to find in a specification, not a design document,e.g., security, privacy, legal.
Sorry for being pedantic.
It reads more like a CONOPS or a software architecture document, but its not detailed enough from a high level perspective, and too detailed at a low level perspective (ie. it has implementation details in a few places you would expect in a higher level design doc).
In that light, I'm not sure who the audience would be in a corporate environment. Is it for architects, other developers, or yourself?
Some items in your doc seem more like non-functional requirements that I would expect to see in a specification, not a design document: e.g., security, privacy, legal.
No feedback on the design doc, except to say it's a good template and very helpful for someone who hasn't worked in a world where design docs have been critical. But can I say we use tinybeans and have a similar complaint (and others), and we would happily jump ship if there was an alternative like that laid out in your example.
I have worked on DO-178C (aerospace) and IEC 62304 (medical device) software design documents and they are much narrower in scope.
OP's design document is comprehensive enough to cover much of ground of the full documentation package for regulated software submissions. Basically all that's left is tracing requirements to design to verification method to verification result.
My problem recently is to have people read design docs I'm writing.
Really nice read. I'll add that it's effective to scope design docs up and down as needed, both in terms of how big your project is and how big your company is. A 50-person startup doesn't need a full design doc with multiple approvers. But a one-pager explaining what you're doing and having some documentation is really helpful even with an engineering team of 5. I'll also still write design docs for code changes that only touch a handful of files, if I feel it's important enough. The process of writing in a concise and precise way for other people to consume also has the positive side effect of making things more clear for yourself, too.
> Interfaces section
Only real criticism I have here, is I would not include any code in a design doc, unless it is really really vitally important. I've seen a lot of design docs (especially in the LLM age, written by more junior staff) which are effectively just an English summary of code. The point of a design doc is (generally) not to explain that you're going to have a WidgetManager and WidgetFactory class and what specific properties and methods they have, it's to explain how the widget creation workflow works and maybe you have the WidgetManager/WidgetFactory in an architecture diagram. As a general rule, if you're starting to include actual code, you've gone too low-level, IMO.
> Not all design decisions are equally important. Some choices are more permanent than others.
At AWS one of the corporate culture memes was calling a decision either a "one-way door" or "two-way door". Just asking yourself the question, if we had to walk this back, is it truly irreversible or just an inconvenience? Turns out most day-to-day decisions are two-way doors, particularly engineering ones. Even if the choice made is wrong and a bunch of work needs to be done to switch back, it's still preferable to what a lot of companies end up in, which is decision paralysis where every change needs approval from multiple committees, resulting in months or years before work can start. Note that this doesn't meaningfully increase the odds the decisions made are the right ones; it just delays the implementation and diffuses responsibility if the wrong decision was made.
> A from-scratch rewrite would never work, and even if you manage to write new code in Rails, you’re still maintaining code in two wildly different languages.
Orthogonal to the article, but this line of thinking (including the link to the classic 2000 "Things You Should Never Do, Part I" article[0]) may be worth reviewing in the post-LLM world; for all their flaws, LLMs are spectacular at language-to-language translation, and we already have one major project released[1] that shows porting a relatively large and mature project from one language to another is possible. Not to say that it's the best use of your time, or that you shouldn't do your due diligence and pick the right language up front, or even that the original 2000 article was about a language-to-language rewrite (the Netscape rewrite was an architectural redesign).
[0] https://www.joelonsoftware.com/2000/04/06/things-you-should-...
[1] https://bun.com/blog/bun-in-rust
OP here.
Thanks for reading and for the thoughtful feedback!
> Only real criticism I have here, is I would not include any code in a design doc, unless it is really really vitally important.;
Yeah, that's fair. If I were setting guidelines for a large org, I'd maybe discourage code snippets in design docs, as it's hard to know when is too much. At my last company, the dev team was just 3-4 people, and I found it helpful to have little snippets in design docs especially when we're talking about semantics of a new library or how to migrate existing code to a new system.
> Orthogonal to the article, but this line of thinking (including the link to the classic 2000 "Things You Should Never Do, Part I" article[0]) may be worth reviewing in the post-LLM world; for all their flaws, LLMs are spectacular at language-to-language translation, and we already have one major project released[1] that shows porting a relatively large and mature project from one language to another is possible.
Yeah, I agree this could change with LLMs, but I think Joel is still correct up to today. Bun is an interesting case because it's friendliest possible conditions for an LLM rewrite (self-contained inputs and outputs, easy to test old implementation and new implementation side by side, huge test corpus w/ third-party tests). I haven't followed it closely, but it seems like the jury's still kind of out as to whether the rewrite was a good idea.
[delayed]
it would not be "fun" to financially penalize my coworkers for their mistakes, no.
Not what he meant, but for an outsider it could be hilarious to watch the company tumble because of that rule.
Claude, write a skill to create design docs as per this blog post /s
In all seriousness a big chunk of my work is reviewing docs and 100% of the design docs I read these days are generated and there is a lot of slop. I have to parse them with AI to make sense of them, contributing to the problem. I wish people would follow a sensible set of rules like this one.
Did anyone have any solution to this dread? Or cracked the code on how to write docs that have other agents as their primary audience?
>Did anyone have any solution to this
Yes. Don’t “write” your design docs with AI. If you can’t personally enforce that, get your manager to.