I like doing things. I like to be occupied with something, spend my skills, knowledge and willpower on it. In other words - I like projects.
Getting a new idea for a project is a wonderful thing. It's a proof my background processing works, and everything I read, watch or listen to gets condensed into some new thing I can try. These ideas are never world-changing, but they still always feel like small epiphanies.
And I can usually start working on it very quickly. Even worse, if the impulse is strong enough, I can't not do it. Some people say the first step is the hardest, but that's hilarious to me. Starting is the easiest. I could start three new things now if I wanted to. I'm very good at starting.
There is however an other side of that coin, and that is finishing stuff. Of course, you can drop your projects whenever you want and go on with your life. But obviously, you cared about those ideas, and it's not as easy to forget them. But it is easy to lie to yourself that you'll get back to them.
And that right there is where the torture begins. I can not forget them. They stay in the back of my mind for months or years at a time, just waiting for attention that they will likely never get. This is seriously causing me non-negligible amounts of emotional turmoil throughout my days.
And before you say: "Go get some real problems in life", let me just remind you that this is my blog and I can write whatever the hell I want here. Here, take a look: fdkslsd klsjdkl sdf.
Finally realizing the problem made me make a list of all the unfinished projects I have, and start hunting more actively for some semblance of "closure" on each of them.
This blog post is a closure artifact for one such programming project.
A few months ago, I met Smetko. And the guy seems to have a similar diagnosis. Not a long time has passed until someone had asked "Hey, wanna do a project together?" And even faster the answer to that was a yes.
I rarely did side projects with friends. I always wanted to, and have even explicitly asked people about it, but never got to do anything substantial that way. Maybe our generation is too individualistic. Maybe we're just programmers. Whatever it is, my side projects were 95% solo efforts.
So it was nice to share a project with someone. Not the least because of the accountability - unlike the majority of side projects in the world, we actually made what we set out to! It was a very simple MVP though, but still - a lot of similar things I would've dropped even halfway to that.
The idea that started it was this: AIs are very good at parsing images now. Let's build an app that scans some real-life artifact and then analyzes it somehow. We decided the artifact would be a receipt, and so the app would be an expense tracker.
We set out to build it using web technologies and publish it as PWA, to not have to mess with Google/Apple app stores.
I don't want to promote the project here, because with the current feature set, this is not something anyone will want to use. It also looks awful and its authentication model is "uhhh, interesting" at best.
But I am writing about it, so I guess I have to link it. It's live on receipix.com.
Your first thought would be: "What kind of design is this?"

Well, yeah, none of the four people on this project could even pretend to be a designer. I myself am horribly bad with any of the visual arts.
But as a professional app-maker and a wannabe generalist, I still try the web design thing here and there. I do it in hopes one of the two things will happen. One: either I will finally understand how design works and become a truly-full-stack developer. Or two: in fumbling with these things, I will come up with a design solution completely novel, something simple and straightforward that will save the web as we know it. So far none of those two things have happened.
But I still like to exercise my mastery of this civilization-important skill that is "making websites and apps" anyway. It was fun, and to me, this UI is very functional. It is also green, because blue didn't look any better.
I have tried AI coding tools before. Copilot is great for autocompleting repetitive stuff. Websim can make an useful app, although it chucks everything into a single HTML file. But for everything more complex, I wasn't convinced it can do the job.
That is, until I tried v0.dev. I only tried it when I was like 90% done with my frontend, so I didn't want to scrap what I already had. But the results are undeniable.
This thing spits out a React app that looks better than anything I could've ever done, and it does so in seconds. It lays out the code in separate files, allowing you to edit them as you see fit, then continue prompting for more changes.
When I tried this, I felt a loss of time, like someone had taken the days and weeks that I spent learning these technologies away from me.
To save myself from an existential crisis, I decided to feign ignorance and still keep my hand-crafted artisan UI. As said before, this is not about satisfying the stakeholders, but a fun "let's make an app" thing.
But the truth is - when I went back to finish the remaining 10% of the UI, I did feel a bit like a madman, writing Javascript with a chisel and a stone, while just outside the window there was a technological singularity happening.
So with that said, I don't think I'll be writing the frontend manually ever again. Which, well, for the reasons I wrote in the React Still Feels Insane And No One Is Talking About It - it might not even be that bad.
There is one more "interesting" thing about this project.
After you do so many side projects, you get extremely bored of repeating some things that are on their own extremely boring. Yeah, I'm talking about the authentication flows.
I do have a working backend for it that I reuse across all my projects, but still, I'd have to integrate with it, copy-paste the login screens and adjust their styles, then create a test user account just so I can use the app. It's all just uhhh, can't we do something more interesting?
So we rolled out something ourselves. Instead of a classic username and password combo, you simply have a... client-side generated user ID. Yes, that's right.

How it works: you open the app and it generates a UUID locally. That UUID is you - it's your username, your auth token, your everything. The app sends it with every request. The backend stores all your scanned receipts under that UUID, and retrieves it the same way later. What do you mean by "password"?
I know, I know. But this thing works. User can just open the app, immediately be "logged in", and start using the app right away.
It feels like it's all local, but it's stored on a server. To log in on another device, you export this UUID on one device and import it on another.
To log out, you click "Log Out" and the app clears the UUID out. You just hope you exported that UUID somewhere, because you won't be able to log in again without it.
But if that happens, you can just call me, and I'll tell you your UUID, because it's all stored unencrypted in a SQLite database.
Go on, call the cops. I'll wait. But good luck, because I'm behind seven proxies and a CGNAT.
Me and my friends have a concept of a "tech suck", more commonly written down as "tehh succ". It's simply when technology fails to work at some trivial case where you'd never even imagine it could fail.
The biggest tehh succ in this project, by far, is the camera browser support. It turns out you simply can't have a reliable autofocus working in the browser. I tried hacking it myself, tried some of the libraries, but simply nothing works.
Check out this StackOverflow answer that just says: "This is impossible right now." And if you wanted something more sophisticated like tapping on the part of the image where you want the focus - you know, basic feature all camera apps have for the last 10 years - no, just stop it, this is impossible on web. Not even camera library makers bother adding it.
The entirety of control you have over focus is a method called applyConstraints where you can set focusMode to continuous. But these are merely suggestions - the camera doesn't really have to do anything, and it likely won't.
Curiously, this works better on my crappy $50 Logitech webcam than it does on my $1000 phone. So my guess is that this may have worked fine before, but the modern AI-powered cameras are so complicated that the browser APIs don't know how to handle them.
Whatever it is, it basically makes PWAs a very bad fit if you want to make a camera-based app. The only real alternative is to make it full native, roughly doubling the time it would take you to ship it.
While on the topic of PWAs, this brings us to a second "tehh succ". From my previous experiences, I expected the Javascript service worker support to be a pain, but I went to implement it anyway. I lost so much time and sanity just making it work that I decided to drop it halfway and leave this "app" as a regular, non-PWA, non-"app" app.
Overall, this was a fun experience, but ultimately we decided to drop the project. Definitely so for the foreseeable time, and highly likely so to be for ever. As they say it in the music biz: an indefinite hiatus.
The first reason, the most honest one - we simply got bored of it. It's not that interesting of an idea to spend our scarce free time on it.
The second one - there's a threshold where a fun side project starts to feel more like a job, and I believe we're here now.
We've got this MVP going, but if we were to keep at it until we built something really usable, we'd have to churn out a lot of boilerplate CRUD. For example, you can't just have a "scan a receipt" feature without having an "edit receipt" form in case AI reads something wrong. You'd then also need a "create receipt manually" form, which might be the same one, but it's still a work you need to do on frontend and backend.
Then eventually, we'd have to replace our shoddy authentication model with the proper one, the same one we implemented 100s of times before on the other projects. And as you can imagine, this does not sound very interesting. It sounds like a job instead.
And the third reason, if I had to name a technical excuse on why this project wouldn't work, it would be: camera support. I still don't believe modern web can't handle autofocus well, but I guess that's where we are.
While we did drop the project, that's in no way saying this was a waste of time. We did make something, we hung around virtually talking about technology and life, and we learned stuff. All good things in my book.
But the best thing about it is that we have, in some ways, finished it. In this modern hectic world, where things just appear and appear without anything seeming to have a satisfying end to it - it's nice to get a sense of closure on something.
So there's a feeling of relief, of an itch successfully being scratched. There won't be any more of that psychological torment reminding me of "that one project" that I wanted to finish, but never really did.
We have bent the definition of done just enough to cross this project off our mental todo lists. All our minds are at ease now.
Until the next project, of course.