Crafting Soreo
• 6-minute read
In early 2025, as I was finishing my engineering degree, I finally had enough time to take on a more ambitious side project. For years, I had wanted to build software that was truly my own: something shaped by my own ideas, taste, and attention to detail.
This is how Soreo started.
Sticking to an Idea
Around that time, I was really into pixel art aesthetics (and I still am). I started wondering:
Why aren’t there more mobile apps that use pixel art for their user interfaces?
The idea was simple: build a small app, but give it a completely original interface made from pixel art. A habit tracker (how original) would be a great fit for this.
For the name, I experimented with some Japanese words related to habits and tasks. I found out that “Sore o” roughly meant “that,” referring to something you do or act upon. It was short, sounded great, and wasn’t really used elsewhere. I just hope this doesn’t sound ridiculous to a native Japanese speaker.
I also had a bad habit of abandoning side projects after a few weeks. By deliberately keeping the scope small, I thought I could actually finish this one and publish it fairly quickly.
…
It took me half a year.
Design as a Non-Artist
I was heavily inspired by the magnificent work of mugi, whom I had previously commissioned to create my profile picture. I wanted the app to capture that same kind of cozy, colorful pixel art vibe.
The design process was meticulous. I went through many iterations, all of which looked horrendous. But after enough attempts, I gradually learned what worked and what didn’t.
Eventually, I had something I was happy with. All that remained was figuring out how to turn that pixel art design into a truely native app. I soon understood why so few apps took this approach.
Development
Soreo was my first real React Native app. I had to learn the framework while simultaneously figuring out how to turn an unusual design into an actual product. The Expo documentation was an amazing source of knowledge and code examples, and the overall experience felt much better than when I had first tried the framework a few years earlier.
While figuring out the architecture and learning how to write good React Native code, I also had to find a way to make the pixel art components actually work.
Oh, and I almost forgot: it had to be responsive too.
Responsiveness
Using images would have made responsiveness difficult, while drawing everything on a canvas would have added another layer of complexity. I eventually settled on building the interface out of actual React Native View components.
That decision came with its own limitations. For example, I could only reasonably make a PixelView with one or two pixels of “corner rounding”. Anything beyond that quickly became impractical and risked introducing unnecessary performance overhead.
My approach was to layer two View components on top of each other to form the background: one extending horizontally and the other vertically, creating the illusion of slightly rounded pixel corners.
For the rounder variant, I used three views instead of two: one extending vertically, one horizontally, and a third filling in an additional pixel around each corner.
Chasing Performance
The hardest challenge during development was performance. Whenever I build software, I expect every interaction to feel extra smooth. With the constraints imposed by the design and all the animations I wanted to add, achieving that level of fluidity ended up being particularly tricky.
Along the way, I learned all sorts of techniques for improving performance in a React Native app:
- Memoizing components and computations where it actually mattered (and later adopting the React Compiler once it became available).
- Virtualizing long lists of components.
- Using Reanimated to run animations outside the main JavaScript thread.
- Keeping frequently changing state as local as possible.
- Avoiding expensive work during renders.
- Using React Native Skia to render a large number of simple components. I used it for the timelines and the difference with native was night and day.
…and plenty of smaller optimizations along the way.
Most of them could essentially be boiled down to one principle: Avoid unnecessary re-renders AT ALL COSTS.
Building Without AI
One decision I made early on was not to use AI for either the design or development of Soreo.
I wanted this project to be entirely mine. I wanted to struggle with the design, figure out the architecture, encounter limitations and find solutions myself.
It certainly made some parts of the process slower, but that was also the point. Soreo was as much about learning how to build a product from scratch as it was about the final app.
I wanted to understand every decision that went into the app, even when that meant learning things the hard way.
Special thanks
A huge thanks to mugi, whose work inspired much of the visual direction of Soreo (and who was kind enough to be cool with it), and to Jubilee for letting me use one of her wallpapers in the app.
And thank you to Weny Arts for creating Soreo’s logo. This little guy is adorable.
What I Learned
I really enjoyed those six months experimenting with Soreo. I loved having ideas, failing, and iterating until something finally clicked. I loved watching the app slowly take shape, and feeling proud of myself for all the invisible challenges I had overcome along the way.
I also had to learn when to move on. The design could have been more coherent. The code could have been cleaner. The performance could have been smoother. There’s always one more thing you could tweak or rethink.
But at some point you have to call it finished.
So, onto the next project!