Design the empty state first, not the happy path
Eight years as a product designer taught me one habit that changed how I write code: design the empty state first. Why the states you skip are the product.

Before I wrote code for a living, I spent eight years as a product designer. People assume the thing that carried over was taste, or empathy for the user. It was neither. The habit that changed how I write code is smaller and stranger than that: a designer draws the empty screen before the full one.
Ask a product designer to design a dashboard and the first question back is "what does it look like with nothing in it?" Not the version in the pitch deck, dense with charts and green numbers. The version on day one, when the user has added nothing yet. The empty state. Designers start there because that is the screen most users actually see first, and the one that decides whether they come back.
Engineers do the opposite. We build the happy path, the screen full of data, the flow where every field is valid and the network never drops. Then, if there is time, we bolt on the empty state, the loading spinner, the error, the row that is three thousand characters long. We call these edge cases. Design taught me they are not edges. They are where the product lives.
The happy path is the demo
The happy path is the version you show in the demo. One clean input, a friendly operator, everything populated. It is an anecdote. Your users do not live there. They live in the empty account, the failed upload, the search that returns nothing, the form submitted twice. If you designed those states last, you designed the product last.
This reframes a lot of engineering decisions. The question stops being "does it work" and becomes "what does it do with nothing, with too much, with the wrong thing." A function is not done when it returns the right answer for the right input. It is done when its behavior for the empty list, the null, and the timeout is a decision you made on purpose instead of whatever happened to fall out.
Start from the empty state
The most useful thing I took from design is the order of operations. Design the empty state first, then the error, then the overflow, and let the happy path be the easy one you fill in last, because by then you already know the shape of everything hard.
In code this looks like writing the zero case before the general one. What does the report show with no data. What does the API return for a user who has done nothing yet. What happens the very first time, before anything exists. An empty database is not a footnote, it is the first thing a new user meets, and it is usually the least designed surface in the whole product.
Designers have treated this as real work for years. The empty state is a studied problem with its own literature and patterns. Engineers mostly rediscover it in a bug report, three sprints after launch, when someone finally opens the app with a fresh account and finds a blank void where the product should be.
What eight years actually taught me
Not empathy. Order. Design is the discipline of building the states nobody demos: the blank, the broken, the too-much. The happy path takes care of itself. Almost everything a user remembers is one of the states you were tempted to skip.
The happy path is the demo. The states are the product.