It is a conversation between the developer and the user.
Quiet, simple and built with the kind of intention that does not scale but does endure.
It is a conversation between the developer and the user.
Quiet, simple and built with the kind of intention that does not scale but does endure.
Not that I get to build whatever I want, but that I get to build things that feel aligned with how I think.
If the apps feel human, it is because they come from a human, not from an optimisation process.
Not that I get to build whatever I want, but that I get to build things that feel aligned with how I think.
If the apps feel human, it is because they come from a human, not from an optimisation process.
I see them as personal artefacts.
They are not defined by scale, but by intention.
They carry the biases, the limits and the care of the person who built them.
I see them as personal artefacts.
They are not defined by scale, but by intention.
They carry the biases, the limits and the care of the person who built them.
Every time I say no to a feature, I am protecting something that matters to me.
Every time I refactor code, I am shaping the app in a direction that feels more honest.
Every time I say no to a feature, I am protecting something that matters to me.
Every time I refactor code, I am shaping the app in a direction that feels more honest.
No recommendations, no automated behaviour, no attempts to influence user decisions.
Not because these things are bad, but because they do not match how I want tools to behave in my own life.
No recommendations, no automated behaviour, no attempts to influence user decisions.
Not because these things are bad, but because they do not match how I want tools to behave in my own life.
I like clarity, predictable navigation and features that stay quiet until the user needs them.
This is why the apps feel calm.
Not by design trend, but by personality.
I like clarity, predictable navigation and features that stay quiet until the user needs them.
This is why the apps feel calm.
Not by design trend, but by personality.
They avoid noise because I avoid noise.
They do not push notifications unless absolutely necessary because I dislike being interrupted.
These are not marketing angles.
They are personal defaults expressed in software.
They avoid noise because I avoid noise.
They do not push notifications unless absolutely necessary because I dislike being interrupted.
These are not marketing angles.
They are personal defaults expressed in software.
It is not who I am today, but it is part of how I got here.
And in a strange way, it keeps me honest.
It reminds me that in a few years, today’s code will also look unfamiliar.
And that is exactly how it should be.
It is not who I am today, but it is part of how I got here.
And in a strange way, it keeps me honest.
It reminds me that in a few years, today’s code will also look unfamiliar.
And that is exactly how it should be.
Growth does not happen in big leaps.
It happens quietly, diffused across thousands of lines of code and hundreds of decisions you barely remember making.
Growth does not happen in big leaps.
It happens quietly, diffused across thousands of lines of code and hundreds of decisions you barely remember making.
You become more patient, more pragmatic, more willing to let go of elegant solutions in favour of resilient ones.
You stop fighting the framework and start working with it.
You become more patient, more pragmatic, more willing to let go of elegant solutions in favour of resilient ones.
You stop fighting the framework and start working with it.
Other times you discover a clever trick you forgot you ever wrote.
Past you was not always misguided.
Other times you discover a clever trick you forgot you ever wrote.
Past you was not always misguided.
You want to rewrite everything, but rewriting is almost never the right solution.
Old code carries context.
It reminds you how the app evolved and why certain decisions were made.
You want to rewrite everything, but rewriting is almost never the right solution.
Old code carries context.
It reminds you how the app evolved and why certain decisions were made.
Structure is clearer, responsibilities are cleaner, fewer magic shortcuts, fewer hidden traps.
It is not perfect, but it has intention.
It reflects a way of thinking that became more stable.
Structure is clearer, responsibilities are cleaner, fewer magic shortcuts, fewer hidden traps.
It is not perfect, but it has intention.
It reflects a way of thinking that became more stable.
Some parts feel solid, others feel cautious.
You can tell I was starting to understand what long term maintenance truly means.
You see the moment where you stopped writing code for yourself and started writing it for the future version of you.
Some parts feel solid, others feel cautious.
You can tell I was starting to understand what long term maintenance truly means.
You see the moment where you stopped writing code for yourself and started writing it for the future version of you.
Different patterns, different assumptions, different fears.
I was more defensive, less confident, sometimes too clever, sometimes not clever enough.
Reading it now is strange but also grounding.
Different patterns, different assumptions, different fears.
I was more defensive, less confident, sometimes too clever, sometimes not clever enough.
Reading it now is strange but also grounding.
It is to build a product that recovers gracefully, even when the unexpected happens.
This is what makes good software feel solid, even when the code behind it is constantly evolving.
It is to build a product that recovers gracefully, even when the unexpected happens.
This is what makes good software feel solid, even when the code behind it is constantly evolving.
They teach you humility.
Software is full of invisible states and unpredictable interactions.
Even simple apps hide a world of complexity behind the surface.
They teach you humility.
Software is full of invisible states and unpredictable interactions.
Even simple apps hide a world of complexity behind the surface.
A missing guard, a race condition, an assumption that does not hold in certain contexts.
Tiny things with big consequences.
You patch them carefully, test again and hope that the silent chain of events no longer appears.
A missing guard, a race condition, an assumption that does not hold in certain contexts.
Tiny things with big consequences.
You patch them carefully, test again and hope that the silent chain of events no longer appears.
You see the exact moment where the app hesitates or misbehaves.
Small clues that reveal where your mental model does not match reality.
You see the exact moment where the app hesitates or misbehaves.
Small clues that reveal where your mental model does not match reality.
You read logs, compare edge cases, isolate conditions, search for patterns.
You remove possibilities one by one until only a few remain.
It is slow, sometimes frustrating, but it is the only reliable path.
You read logs, compare edge cases, isolate conditions, search for patterns.
You remove possibilities one by one until only a few remain.
It is slow, sometimes frustrating, but it is the only reliable path.
What could cause the behaviour
What part of the flow is fragile
Where could a silent failure hide
You treat the bug like a story with missing pages and try to guess the parts that are not written.
What could cause the behaviour
What part of the flow is fragile
Where could a silent failure hide
You treat the bug like a story with missing pages and try to guess the parts that are not written.
You accept that you know less than you think.
Recreating the user’s exact setup is almost impossible.
Different models, different OS versions, different data, different timing.
You start by admitting that your assumptions are probably wrong.
You accept that you know less than you think.
Recreating the user’s exact setup is almost impossible.
Different models, different OS versions, different data, different timing.
You start by admitting that your assumptions are probably wrong.