Simon Tatham, the creator of PuTTY and a few other key technologies that are widely used, came up with the word in the early 2000s, and in his blog he created a post about it. I think we are going into the era of development where symbiosisware is going to become increasingly prevalent.
Unlike vaporware, the software that companies claim to be building but never publish, symbiosisware is software designed for the individual developer, the person who created it. You can think of your .zshrc as a piece of this type of software. Built for the person using it. As Simon continues to describe it, symbiosisware is often for the individual but can turn into a piece of publishable software, and I found that it resonated with me quite a bit.
Recently one of the things I have been building is a Git client. The main intent you might presume to be to gain a deep understanding of Git or understanding Git clients. Perhaps an interest in how Git hosting works, or insight into the comical first commit that Linus made for Git itself.
Under this definition of symbiosisware you can argue that Git started as a piece of symbiosisware. Linus was having an issue with version control management for his specific workflows and then, lo and behold, he built Git. I don't think when he built it he thought it was going to become as widely popular as it is, or a 21 year endeavour either.
So the reason I built a Git client, and I will publish it for more general availability, is a simple one. GitHub Desktop's UI was a little old for my taste and it had a minimum width that was larger than half the screen size of my laptop, so it didn't work with my tiling system. Also I watched Cyberpunk Edgerunners recently and I wanted something with a better theme. I evolved it a bit further to help me work with my workflows. I have a ton of projects and therefore repos, as anyone who has hovered over the products page or goes to romans.dev can easily see. I have built a bunch of things and want to continue to keep building. I do greatly enjoy this Git client and have continued to work on feature parity and getting it completely finished and feature matching the official Microsoft one, or ensure that it covers my workflows at the minimum.
As I have built this piece of software out and greatly enjoyed the process of doing so, for the first time I decided to lean super hard into AI, letting Claude write all of the code once I had set up the structure of course. I primarily did this because I thought no one else was going to really use this and I wouldn't have to support customers, so minor bugs don't matter. I didn't have the time to review everything that Claude was pushing out for this project because my main focus was on my other projects, like Statio, so letting this one instance of a claude code cli run and continually check the plans and run audits periodically seemed to be the right move.
As I came to the end and am now primarily using it aside from some edge cases that I discover here and there, I thought to myself that over the course of 2 weeks I was able to build a thing, and that thing is useful to me, probably only me, but nonetheless a tool for myself. I thought it was really cool that I trusted AI more than I already did for code generation, and while I have had to instruct a few refactors along the way my end product was a product for myself.
Taking software from symbiosisware to general availability
A Git client might be one of the worst things to try to take from a personal project to general availability, due to the fact that if something goes wrong it could mess up your project. And while I have tested most workflows and am trying to make it "AI friendly", I finished the original working version that I liked by the end of August, and two weeks later and running a ton of workflows I still don't feel quite close enough to getting it out to the public. Integrating OAuth for GitHub and GitLab, ensuring I have parity between those two services (I have some client projects in GitLab, so it's a very valid use case), working to ensure my E2E testing works, adding CLI commands to interact with the features I built into it. It will take me a number of weeks to feel confident to throw up the website and make it readily available for download, with automatic updates, and more control.
The biggest difference between software for an individual versus an audience is that a small bug multiplies by the number of people impacted. Something Simon does a great job of describing and diving deeper into in his post.
Are we going to go into an era of symbiosisware development?
With AI making it far easier to develop working software we are already seeing the flood of tools and software being created with AI driven development. However, I think that there needs to be a quick distinction made here. One-off automations for companies, despite a company in the US being given the same rights as a person, are not built for an individual, and therefore automations that companies build for their own processes are not symbiosisware. They have to be actively maintained and more than likely multiple people are using them or dependent on them. I believe that individuals are going to develop a wide variety of tools, and I think there is going to be a flood of these tools that get created privately and that people try to push out more publicly.
We may have just entered the symbiosisware era of development, and that can be a good thing. More tools for solving unique workflows. That is how Git started, and a number of other crucial pieces of software that the world is dependent on today: building a thing to solve a problem that an individual is currently facing, then discovering through the continuous development of that thing a community of persons that need it, and seeing the evolution of what that piece of software started as versus what it becomes.
Top comments (7)
"The biggest difference between software for an individual versus an audience is that a small bug multiplies by the number of people impacted" is the sentence that should be tattooed on every indie developer's forehead.
I've built tools for myself that work fine for 6 months, and then I share them with one friend and discover 15 edge cases I never hit. The code didn't change — the audience did.
Curious if you have a "release checklist" for symbiosisware. Something like "if a user deletes their repo, does the app crash?" that forces you to think about the paths you never take.
It's hard to come up with a given checklist because it depends on the project. The best checklist I can usually think of is, can it pass the mom test. Is the software simple enough and straight forward enough for my mother to use. What edge cases can I think of that she might hit. But it should be as simple as possible to use and straight forward with guardrails basically. Depends on the project but I have found if you refine with that mindset it helps a lot.
"The mom test" is the best checklist I've heard for this kind of software.
It forces you to think about all the implicit knowledge you have that your users don't. You know where the button is, what the error means, and why the app crashed. Your mom doesn't.
The only caveat: if the software is for developers (like a Git client), your mom isn't the target user. But the principle still holds — replace "mom" with "a developer who has never seen this tool".
I’d try that with a developer who hasn’t used the client before, on a disposable repo. When something fails, can they tell what changed and what to do next without asking you?
Which failure case would you have them try first?
That's a brilliant test scenario. A fresh developer in a disposable repo is the ultimate test of whether your error messages actually mean something, or if they just assume "well, the original author knows what this means."
To answer your question: I'd have them try a missing or misconfigured environment variable first.
In "Audience of One" software, the single user usually has one specific way of running things. If a config key is missing, or an API key expires, the app usually crashes with an obscure stack trace. The test is whether the new dev can look at the error and know exactly which file to open and what to put in it without Slack-messaging you.
A close second would be malformed user input—since you're building for exactly one person, their specific quirks (e.g., pasting an Excel table instead of a CSV, or a weird date format) are the most likely points of failure. If the app can gracefully catch that and tell the dev "Hey, the input format was wrong," rather than just throwing a 500 Internal Server Error, you've built a resilient system.
What's the most obscure edge case your "audience of one" has managed to trigger?
Missing config is a good place to start. I’d want the error to name the missing key and where to set it, without printing the secret.
Can the developer fix it and retry without asking you? Or does that just uncover another unexplained failure?
Spot on. A good error message acts as an onboarding doc: "Missing API_KEY, add it to .env" takes 10 seconds to fix. But if fixing that immediately uncovers a cryptic database timeout, the test fails. It needs to fail predictably, one clear blocker at a time.