M
Muhammad Abdullah
Guest
It Started With One Simple Thought
I have always thought a journal is one of the most precious things a person can have. It doesn't just contain words. It contains memories, thoughts, experiences, and small moments that eventually become part of who we are. But when I looked at digital journal apps, something felt missing.
Most of them looked like note apps. You open an entry, type something, scroll through it, edit it whenever you want, and move on.
That works functionally. But I kept thinking:
If our memories are so important, why does the digital place where we keep them feel so ordinary?
That became the starting point for Book of Me. I didn't begin with a huge product roadmap.
I had one idea: I wanted memories to exist in the shape of a book.
Each memory would feel like a page. And when many memories came together, they would form the story of a person's life.
That was it.
At least, that's what I thought I was building.
What If a Digital Journal Couldn't Rewrite the Past?
There was another idea that became important very early. Most digital journals allow you to edit an entry after saving it.
But life doesn't work that way. You can remember something differently later. You can understand it differently. You can regret what you wrote. But the moment itself already happened.
So Book of Me became a non-editable memory journal.
Once a memory is saved, it becomes part of the book. This isn't meant to make the app restrictive for the sake of being restrictive. It is connected to the idea behind the product:
Your memories are part of your story, not a document that needs constant rewriting.
The First Version Wasn't What I Imagined
I started building in the first week of August 2026.
One developer. No team. No designer. No guaranteed outcome.
I built the first version in Flutter. I could already add memories and photos, and the basic idea existed. But when I looked at it, I wasn't satisfied. I wanted the app to feel like a real book, so I initially experimented with a two-page/open-book layout.
The problem was the screen.
A physical book has enough space for two pages to sit naturally beside each other. A phone doesn't. The two-page design looked less like a book and more like a small interface trying to imitate one. So I changed direction.
Instead of copying a physical book literally, I decided to preserve the feeling of a book while adapting it to a phone.
That meant using a single-page experience.
It was one of the first lessons of the project: I wasn't building a physical book. I was trying to recreate what makes a book feel special.
The Design Looked Like a Book. The Behavior Didn't
I spent more than ten hours working on visual assets and variations to make the interface feel vintage and physical. Eventually, I had something that looked much closer to what I imagined.
But there was a major problem.
The memory page was scrollable. It looked like a book, but it behaved like a notes app. If the text became too long, the user could scroll inside the page.
That broke the illusion.
In a real book, when you reach the bottom of a page, the text doesn't become scrollable.
It continues onto the next page.
So I made a difficult decision: I threw away a large part of the work I had already spent hours creating and rebuilt the book view mostly with code.
The goal changed from:
“Make it look like a book.”
to:
“Make it behave like a book.”
That distinction became one of the most important parts of Book of Me.
The Two-Day Pagination Battle
This became one of the hardest technical problems in the entire project.
I needed the text to move naturally from one page to another. The rule was simple: text is never scrollable. When a page is full, the text continues on the next one.
My first version was inspired by how something like Microsoft Word handles text, and it wasn't right. Sometimes the next page started while there was still an awkward empty half-line on the previous page. When I fixed that, I created the opposite problem: too much text was pushed onto the page and overflowed.
The problem was not simply "count how many words fit." The space text needs depends on font metrics, line height, available width, padding, and what else is on the page. So I stopped counting and started measuring, like testing text on invisible paper.
- Step 1: Budget the space. The first page has less room because of the date, title, divider, and photos. Later pages only lose the page number. I measure the date and title with
TextPainterand reserve fixed heights for photos:
Code:
double firstPageBodyHeight({required String date, required String title, required int imageCount}) {
final available = pageHeight - (verticalPadding * 2);
final pageNumArea = 6.0 + pageNumberHeight;
double header = getDateHeight(date) + dateTitleSpacing
+ getTitleHeight(title) + titleDividerSpacing
+ dividerHeight + dividerBodySpacing;
if (imageCount > 0) header += imageHeight(imageCount) + imageBodySpacing;
return math.max(0, available - pageNumArea - header);
}
- Step 2: Lay out the real text and count the lines that fit. For each paragraph, I build a
TextPainterwith the exact style the page renders with, at the page's content width:
Code:
final painter = TextPainter(
text: TextSpan(text: para, style: metrics.bodyTextStyle),
textDirection: TextDirection.ltr,
strutStyle: metrics.bodyStrutStyle,
)..layout(maxWidth: metrics.contentWidth);
final lm = painter.computeLineMetrics();
double used = 0;
int fit = 0;
for (final line in lm) {
if (heightUsed + used + line.height > maxHeight + 0.5) break;
used += line.height;
fit++;
}
- Step 3: Find where the last fitting line ends. I sample a point at the right edge of that line and ask the layout which character sits there:
Code:
final sampleY = used - lm[fit - 1].height / 2;
final pos = painter.getPositionForOffset(Offset(metrics.contentWidth - 1, sampleY));
Most importantly, I never wanted the algorithm to cut a word in half. I didn't want "Today I went to the marke" followed by "t..." on the next page, so the split snaps to a word boundary and the text continues naturally.
Three details mattered as much as the algorithm:
- One style for measuring and rendering. The measured text and the displayed text share the same
TextStyleandStrutStyle, so line heights match. - Fixed page dimensions. The book screen always reserves space for the save button, even in read-only mode. Otherwise the same memory would paginate differently depending on which screen opened it.
- No system font scaling. I turn off text scaling for the book. A user's accessibility font size would otherwise silently break every measurement.
As a safety net, each page's body is clipped to its computed height, so a small error clips text instead of making the page scroll.
I used AI to help me develop the first version of this algorithm. It got the general idea right but failed in two ways: some pages overflowed (once by 87 pixels), and others broke early and left a half-empty line. What fixed it was making the measuring and the rendering share the same text style, and finding that took most of the two days. The requirement, testing, and debugging came from the behavior I needed from the app.
And I nearly gave up.
After hitting the hard bug, I seriously considered returning to the original scrollable approach. It would have been easier. But that would have meant sacrificing the central experience I was trying to create.
So I kept going. I spent around two continuous days debugging why the text I measured and the text I rendered disagreed.
Eventually, it worked. And that was one of the first moments where I looked at Book of Me and thought:
Now the pages actually behave like a book.
That feeling mattered more to me than the technical achievement itself.
The Product Started Becoming Bigger Than My Original Idea
At the beginning, I only imagined memories in book form. But as I built it, I started asking what else could belong in this world.
That led to the Memory Tree.
The idea was simple: One memory becomes one leaf.
A person's life is made from hundreds or thousands of small moments. Most of them eventually disappear from our active memory. But together, those moments form our story.
So instead of showing users a list of memories, I wanted their collection of memories to physically grow into something.
A tree.
As memories accumulate, the tree grows. And when a memory is deleted, its leaf doesn't simply disappear. It becomes a dead leaf and falls.
That small interaction represents something that a normal delete button doesn't: a memory was once part of your story, and now it is gone.
Then a Tester Changed the Tree
One of my testers suggested something I hadn't thought about.
If every leaf represented a memory, why couldn't the user touch an individual leaf and read that memory?
It was a simple suggestion. But it changed how I thought about the tree. It wasn't just a visual representation of the number of memories anymore. Each leaf represented an actual moment.
So I implemented clickable leaves that let users open and read the memory behind them.
This became one of the clearest examples of why feedback mattered to the project. I didn't have to agree with every suggestion.
But when someone interacted with the product in a way I hadn't anticipated, it sometimes revealed something I couldn't see while building it alone.
I Started Building a World Around the Memories
The original book concept gradually became a larger system.
The Library contains the Daily Journal as well as life chapters such as:
- Beginning
- Becoming Me
- Right Now
The idea behind the chapters is that our memories can become buried under newer memories. Sometimes a small old memory can bring back an entire period of your life.
Book of Me tries to make that rediscovery intentional.
There is also Shared With You, where memories can be shared with another person. I wanted sharing to feel different from sending a normal message. So, instead of another chat bubble, I designed it like a physical letter, including shadows and a more tactile visual treatment.
Even deletion became part of the metaphor, with the interaction designed to feel more like a letter burning away than simply removing a card from a database.
There is also a Time Capsule, photos, background music, sound effects, and other small elements designed around the same principle: Digital interactions should still feel connected to real-life objects and experiences.
Feedback Also Changed the Sound
The visual experience wasn't the only thing that evolved through testing. Someone told me they really liked the background music.
That reinforced something I hadn't initially considered deeply enough: sound could contribute to the emotional atmosphere.
But another friend disliked some of the sound effects. Instead of deciding that my original choice was automatically correct, I added controls so users could mute sound effects and background music independently.
That became another recurring pattern in development: The product wasn't finished when I personally liked it. It had to survive other people's interactions with it.
Features I Chose Not to Build
One of the less visible parts of product development is deciding what not to build.
I considered adding AI because AI features are becoming common in journaling products.
But Book of Me had developed a very specific identity: vintage, personal, emotional, and connected to the feeling of real physical objects.
I didn't want AI to become a feature simply because it was fashionable. So I left it out of the core experience.
I also considered a streak system. Streaks are an obvious way to encourage people to return to an app. But I started thinking about what happens when someone misses a day.
An unbroken streak can feel motivating.
But for another person, seeing that a long streak has been broken can make them feel like they failed. They may simply stop using the app.
That didn't fit what I wanted Book of Me to be. I don't want someone to feel guilty because they didn't journal yesterday.
The purpose is to preserve memories and eventually rediscover them.
I would rather have someone return after six months and rediscover their life than make them feel bad for missing six days.
When “Technically Possible” Wasn't Good Enough
Not every idea survived implementation.
I wanted the book card in the Library to open with a realistic 3D book animation. I managed to get the concept working, but it was laggy.
I spent around eight hours trying to improve it. Eventually I had to make a decision.
I could keep spending time trying to force the animation to work, or I could accept that an impressive animation with poor performance was worse than having no animation at all.
I abandoned it.
That was another lesson: A feature isn't successful because you managed to build it.
If the experience feels bad, the implementation isn't finished.
Monetization Was Another Series of Revisions
The product's monetization also changed several times. Initially, I considered making partner sharing a paid feature.
Then I thought about the user experience. If someone has never used the feature, why would they pay for it before understanding its value?
So I changed the free plan to allow text-memory sharing with up to five people, while keeping photo sharing as a paid capability.
I had initially considered allowing only one free connection, but that felt too restrictive, so I increased it to five.
Time Capsule also has a free allowance.
The life chapters changed as well. Originally, I planned to make all chapters free, but eventually made Beginning free while Becoming Me and Right Now became premium. The reasoning was that deeper exploration of personal history could become part of the premium experience.
Photos created another problem. Free users can save photos, but those photos are stored locally. If the user uninstalls the app, they can potentially lose them. Paid users can have their photos backed up.
But then I noticed another potential problem: What stops someone from subscribing for one month, backing up everything, and immediately cancelling?
So I added a rule around which photos qualify for backup during the active paid period. These weren't decisions I had figured out before building.
They emerged while I was trying to make the product sustainable without destroying the experience for free users.
My First Payments Integration
Book of Me is the first app where I added payments, using RevenueCat.
I kept it simple: one premium access level, and the plan decides the tier. Free, Monthly, Yearly, and Lifetime all work through the same "Book of Me Pro" access, so the app only asks one question: does this person have Pro?
The harder part was deciding the rules. Which features stay free? What happens when a subscription ends? What does a Lifetime user keep forever? I had to settle these before I could build anything.
Building Alone Changes the Process
I'm building Book of Me as a solo developer. I don't have a dedicated designer. I also don't have unlimited resources.
There were times when I was spending most of my available time trying to improve one screen because I had another design idea I wanted to test.
Sometimes that meant rebuilding something I had already built. Sometimes it meant throwing away hours of work. Other times it meant accepting that an idea wasn't worth the performance cost.
And sometimes it meant asking whether I should even continue.
The financial side of building independently makes that question real. You can spend days solving a technical problem without knowing whether the final product will ever generate anything.
The pagination problem alone unexpectedly consumed two days. But that uncertainty became part of the process rather than something I could eliminate.
Then I Found Shipaton
I found Shipaton through an ad. Before that, I didn't know a hackathon could push builders to ship real apps, document the process, and treat payments as part of the build.
I had been building alone, and it showed. Shipaton put me next to other builders and their products, and my bar moved. I wanted Book of Me to be more polished than I would have made it on my own.
The weekly Shipaton letter showed me how other builders promoted their apps and what they did differently from me. Seeing what others shipped each week made me compare my progress honestly, and it pushed me to keep going when I would otherwise have slowed down.
The lesson that hit hardest came from the "Roasting Paywalls" livestream, where Julie, a paywall specialist at RevenueCat, reviewed real paywalls from builders in the community.
Three points changed how I think about my own app:
1. The paywall right after onboarding is the biggest opportunity. She called it a money machine, because most people who finish onboarding will see it, while a paywall buried in the app is seen by far fewer. Her advice was to add one even if the app has a free tier, as long as there's a close button.
2. Sell the problem you solve, not the upgrade. Her advice for indie builders was to skip "Upgrade to Pro," which works for huge brands with millions of organic users. A small app has to communicate its value in the first five seconds. The host made the same point about buttons: a button that says "Start now for $3.99 a month" sells a price, while one tied to what you get sells a benefit.
3. Even the exit button matters. Instead of "Continue with the free version," which makes leaving feel like a good deal, she suggested wording that reminds people what they're giving up, like "Continue with limited version."
She also warned about lifetime plans: users love them, but they're usually worse for the business than renewable subscriptions, so check your numbers before offering one. Book of Me has a Lifetime tier, so that stuck with me.
I haven't built a proper onboarding flow or a proper paywall yet. That's the honest state of the app today, and it's why the guided first-time experience is at the top of my list.
What I'd Tell Another Builder
- Measure text, don't count it. Word counts fail because space depends on fonts, line height, and width. Lay out the real text and see what fits.
- Match behavior, not just looks. A page that looks like a book but scrolls like a notes app is still a notes app.
- Throw work away when it's wrong. I dropped hours of visual assets and an eight-hour animation, and the app got better.
- Say no to features that don't fit. AI and streaks were easy to add, but neither fit what Book of Me is.
- Plan onboarding and the paywall early. I learned this from the Shipaton livestreams, after I'd built most of the app.
What Comes Next
I don't think Book of Me will ever have a final version. The bad designs taught me what I didn't want. The pagination bug taught me what "book-like" actually meant. A tester turned the Memory Tree from decoration into something you can open. And a 3D animation I dropped after eight hours taught me that performance matters more than ambition.
The problem I haven't solved yet is the first minute. Someone who has never used a journal app may open Book of Me and not know where to begin. I'm building a guided first-time experience that shows where to tap, so people reach the emotional part without learning the interface first.
Because I don't want Book of Me to feel like an app someone has to learn. I want it to feel like a book someone has discovered.
And maybe, years from now, when most of the ordinary days have faded, opening it will give someone a piece of themselves back.