Launching Things: AriadneJobs
Last week, I launched my first bootstrapped product - AriadneJobs.com. It was a much longer journey, they I originally imagined, so some lessons learned. Here is a mostly unsorted account of various thoughts I have related to this.
Bootstrapping
I’m quite certain that my initial thesis - “if I’m continuing to work full-time, I won’t ever bootstrap anything” was true. The switch to freelancing gave me just enough of free time to work and iterate on the initial idea. Considering, that the thing I’ve launched was the iteration #3, after a significant pivot and essentially starting from scratch once, I just don’t see how much time it would’ve taken if I only had an odd evening and an odd weekend here and there.
Jumping into and out of client projects already provided a significant challenge. Especially because I had customers using different tech stack. I did work on my ability to switch the gears easily a couple of years ago when I did Advent of Code in 4 different languages, I also repeated that last year. Still, with a very fragmented time and a rather sizeable problem to solve, it was non-trivial.
Infrastructure
Pivoting notwithstanding, freelancing also gave me enough time to build the platform for running things. I can deploy both my and dev versions of my clients apps very easily and cheaply with Github Actions, k3s cluster running on Hetzner, and a bunch of monitoring, logging, visualization, etc. tools I put on top of it. It’s always a work in progress, but there’s something immensely satisfying in just having this ability to start something new easily.
Technical infrastructure is only a part of the puzzle, though. Setting up accounting, billing, taxes, company formation - a bunch of prolonged, bureaucratic processes, that one must jump through. Thankfully, I front-loaded most of this work when setting up my consulting business. Still, a separate entity was needed to release the app + I needed to do Stripe integration and figure out some tax questions (there are different taxes applied if you freelance vs selling a digital product/subscription in Germany).
Stack
Elixir and Phoenix did prove themselves once again as a good and fast way to go from an idea to working software. And iteration speed is incredible when you don’t need to build API layers, wrestle with JS bundler configs, and such - thanks to LiveView. I also tried HTMX for one small thing on the landing page. It’s a good supplement to LiveView, and it’s easy to configure layout templates in such a way that the JS library is only pulled on the pages that use it.
I still like working with Kubernetes. Even though it entails a bunch of silliness, I do like having a vendor-independent way to run my apps reliably-enough, while having unified access to lifecycle commands, logs, etc. I also like that there are integrations between Kubernetes and some major Elixir libraries and tools.
Livebook now allows executing notebooks in a remote, dynamically provisioned runtime on either Fly.io or Kubernetes. This was especially useful. It allowed me to save some time on getting basic metrics and monitoring the launch.
First, you configure runtime, it can also cache dependencies in a PVC…
then you can execute code remotely on the node you wish, and assign results to variables…
and look, we’ve got dashboards at home!
Cutting Scope
The main skill that I have significantly improved due to all of this is cutting scope. Incredible how the relative importance of things change when you can only rely on yourself in a resource constrained environment. It also brings immense satisfaction. I used to hate leaving things slightly undone, and yet now I can enjoy it.
Even though it does mean that some things will be shittier than they can be, it also means that you can move faster. When you don’t have confidence that the picture will lock in place, you just cannot spend extra time on polishing the things you may kill tomorrow.
Yet, eventually the priorities become clear. I didn’t use any fancy project management
approach for this. I just had a list of TODOs in the Readme.md
file in the root of the
repo of the project. I sometimes went through it and reshuffled them in a rough order of priority.
At some point, 2 months before the launch, I put a bunch of those TODOs in a separate list above the others. Reaching those was the scope that I saw for the MVP. I thought I will do them in a month :)
And yes, I do follow my Git for Everything approach pretty thoroughly. Markdown is such a joy, after all. On a side note, I even have my recipes in a git repo. Github’s mobile app is a much nicer interface to read the recipe from while cooking than any cooking websites or apps I saw.
Hopefully, I can cut down the next idea much more. On the launch day I realized that I’ve built two features that were… hopefully useful one day? But I just figured that I could’ve skipped both of those quests completely, which would’ve saved me about 3 weeks (excluding the ongoing maintenance). So let’s see, at least I can hope that my gut feelings did become better.
Ideas
I used to be one of the guys who says “I think I’ve got the skills, I just don’t have any ideas”.
Turns out, ideas are indeed never a problem once you commit to doing it. They come when you work, so the key is just working on literally anything. Once your brain starts treating whatever you’re doing as an idea, it will notice a bunch of deficiencies in it, and will try to correct them, throw in competing ideas, and so on. You will naturally become more likely to find new ideas and look at things around from the perspective of “is there something?”.
Launching
I never have butterflies in stomach or anything like that when I launch something. I thought that it might feel different when I launch something of my own. It didn’t.
But the sense of relief and satisfaction in realizing that I’ve actually finished the damn thing and can do something else next is still immense.
Next
Now the grind of tweaking, adjusting, pushing new features, maintaining feels pretty relaxing versus the pre-launch scramble. I gotta add a changelog to the landing page. I gotta tweak the subscription settings on Stripe. I have lots of ideas for the Funnel view. Search still sucks sometimes, I gotta tweak some things. I need to start doing some ML experimentation on some of the job descriptions I have. There’s a better way of getting the structured outputs from ChatGippity now, I’m still using the agent + validator approach. It’s in the TODOs, and will be in progress shortly.
And I just added What’s New section to the app with a changelog blog.
I saw @levelsio post about his Telegram bot,
and did a rough and quick version of the bug reporting part of it in like 30 minutes with some macro magic.
I can now wrap some code in a block, pass some custom tags to it if I want,
and if that code raises or returns {:error | :exit, any()}
, I’ll get a message from my bot
on Telegram.
guard "adding a job", id: id do
# some code that can raise
# or return {:error, ...}
end
I can just wrap any block of code in this magical invocation, adding any metadata I want (id in this case)…
…and if it fails, I get this message right away.
I’m also dogfooding the app. I’m open to employment for the first time in 2 years, but also still would take freelancing clients until I find something decent. Also, you cannot sell what you don’t use. And no, I don’t expect this thing (or the next, or the next) to generate enough money for me not needing to work for other people. I hope that in a couple of years a bunch of them together might.
If you enjoyed this content, you can sponsor me on Github to produce more videos / educational blog posts.
And if you're looking for consulting services, feel free to contact me .