30th October, 2026
Frolickk - A Case Study on How I Built a Reading App with Claude Code
There was a fourth, personal goal. I've designed products that developers built, but I'd never carried my own design all the way to a working app. I wanted to find out what breaks between a Figma frame and a phone in someone's hand.
Overview
Reading on my phone was a scattered experience. EPUB books lived in one app, PDFs in another, and articles stayed in browser tabs I hardly ever got back to. Wanting to read a book meant searching a website, downloading a file, then finding that file again in another app.
I wanted one calm place for all of it. So I set three goals:
One unified library for EPUBs, PDFs and web articles, with shelves that sort themselves.
No dead ends, I wanted to be able to pull an article with just a link or search a public library like Gutenberg, download a book, and start reading all without having to ever leave the app.
An app that felt premium and considered, a modern design with fluid motion, haptics and considered details.
I started in Figma with a small design system: Open Runde as the only typeface, a defined colour palette, and every component designed in its default, pressed, focused, error and disabled states. That last part paid off later. When a bug turned up in a text field, the fix was usually "use the state I already designed," not "invent something new."
Designing the System


EVERY ISSUE I FOUND WENT BACK EITHER TO CODE OR TO FIGMA.
I can't write Kotlin, so I split the work clearly. I owned the product: the designs, the decisions, the testing and the judgement of what "done" should look like. Claude Code owned the engineering: turning my Figma files into code, and debugging why something broke once I'd found it.
Every build went through the same loop:
Design the screen or fix in Figma.
Claude Code turns it into a test version of the app.
Test on my phone to find out what breaks: reading, searching, downloading, going offline on purpose.
Log what's wrong in plain words, the way a user would say it.
Decide on the fix. If the cause was a code bug, Claude Code fixed it. If the cause was a design decision, I went back to Figma.
How I Worked
A few signature moments sit on top. Long-press a book and its cover lifts into a holographic card that tilts with your finger. The font size control is a drum dial with a buzz on every step.
That loop ran over 20 times between 22 and 26 October. It produced 40+ logged issues, 62 commits and 43 automated tests that stop fixed bugs from coming back.
Step 5 is where most of my design work actually happened. Over those iterations, I got better at telling a code problem from a design problem.
Of the 40+ issues these 5 changed how I think about design.
5 Problems I Encountered Worth Mentioning


SCREENSHOT OF THE LABS SECTION
The blur effect that made the whole app flicker.
In my design, book text faded softly under the status bar. The first build used a live blur to do it. On my phone, the whole page flickered as I scrolled, and it got worse when the word finder was open.
The cause was technical: the book page is a small built-in browser, and copying it every frame to blur it couldn't keep up. In a second iteration Claude moved the blur inside the page. That stopped the flicker but now it left a blurred patch that scrolled along with the text.
I stopped trying to get it to work with code. The blur wasn't what mattered to me; the soft edge effect was. So I went back to Figma and designed a plain white fade that gives the same feeling with nothing to compute. With this, nothing is drawn into the book page at all. Sheets that open over a book use a still snapshot of the page instead of a live blur.
Lesson: when an effect keeps fighting the platform, redesign the intent instead of patching the technique.
The benchmark timings were measured on a computer with the app's own database queries, not on my phone. A phone is slower overall, but the before-and-after ratio should hold.The last row matters to me. Glass, springs, dials, floating download pills and a full speed pass together added just 63 KB to a 14 MB app. Polish doesn't have to cost the user anything.
Where the app stands currently: an installable Android app with over 10,000 lines of code, 43 automated tests and 62 commits, running on my phone.
In the final round, I fixed a lag I'd noticed: books sometimes took a moment to open, and my whole library took a moment to appear at launch and with my library being almost 1 GB in size I wanted the issue fixed. The answer was several small inefficiencies adding up, and fixing them made one of the biggest measurable differences of the project.
Results
Three things I did to give the app its character;
Glassmorphism. The nav bar, menus, sheets, and toasts all use a frosted glass effect with blur, refraction, an edge light and soft shadows. It's the most visible part of the brand, so it had to look right on a real screen, not just in Figma. Apart from being a really cool design style, I also chose it because I believe it's the most complex style (at least with regard to code) and I wanted to really push Claude to see what it could actually do.
Motion. Buttons depress slightly when pressed, sheets and menus grow out of the control that opened them, book covers zoom open into the page they lead to and shrink back when you leave. Everything moves on springs, and all of it can be turned off when someone turns on the "reduce animations" setting on their phone.
Haptics. I treated touch feedback as an important part of the design, not just a finishing touch. I picked each vibration from a labs section I asked Claude to add to specific test builds, on my own phone, rather than guessing from a spec sheet.
At a Glance
TL;DR
I designed a reading app for EPUBs, PDFs and web articles, then built it with Claude Code. I designed every screen and decision; Claude Code wrote the code.
I tested every build on my own phone and logged 40+ issues. Some were bugs. Many were design problems that only showed up on a real device.
The biggest wins came from turning one-off fixes into app-wide rules for motion, haptics and errors.
A final speed & stability optimisation pass at the end cut launch database queries from 7 to 3 and made book libraries load about 2.5x faster in benchmark tests.
Role: Solo product designer
Type: Personal project
Built With: Figma for design, Claude Code for engineering (Kotlin & Jetpack Compose)
Timeline: 22 - 26 October 2026, 22 different versions and test builds
Status: Installable Android app (A.4.5). Not yet on the Play Store
Download Frolickk
Download Frolickk and let me know what you think! A few things to keep in mind.
Frolickk is still in beta testing, so there is a chance you'd encounter bugs. Please email me or reach out on X if you spot any.
Frolickk isn't on the Play Store yet, so clicking on the download link redirects you to the Github repo and you'd have to side-load it from there.
Frolickk is only available on Android for now. (sorry iOS users)
Glass effects that looked right in Figma but off on my phone.
The nav bar used my exact Figma values, but on my phone it was way too see-through. Figma doesn't publish how its Frost setting maps to real blur strength, so the conversion came out roughly half as strong.
Instead of guessing values back and forth, I had a temporary Glass Lab built into the app: live sliders for frost, refraction, depth and light. I tuned the glass on my own screen until it looked right. (doubling Frost from 6 to 12 fixed the nav bar).
The lab also exposed a hidden bug. Glass blurred colours and covers fine, but text behind it stayed perfectly sharp at any setting. The fix applied to every glass surface in the app at once, not just the nav bar.
Lesson: some design decisions can only be made on the real device. When possible build a tool to make them there.
FROM A PASTED LINK OR LIBRARY SEARCH TO READING WITHOUT LEAVING THE APP
Motion that animated from the wrong place.
I wanted iOS-like motion: things should animate out of whatever you tapped. Once that was applied system-wide, a new problem appeared. Tapping the + at the top of Collections made a sheet animate from the top of the screen and travel all the way to the bottom which looked strange.
I turned that observation into a rule, which I call the distance rule:
Sheets always animate in from the bottom of the screen regardless of where the control is. The only exception to this is the reader's title pill which already sits at the bottom of the screen.
Dialogs animate from a nearby option, or simply appear in place.
Screens zoom out of book covers only if the cover is visible on screen. Otherwise they slide in from the left.Lesson: a motion idea isn't complete until you've decided where it shouldn't apply.
TOP: BLUR BOTTOM: FADE
Haptic feedback that was added screen by screen.
When I asked Claude for a list of every haptic in the app, I noticed certain gaps. Only one error, "Definition not found," had haptic feedback. Deleting a collection used that error's haptic pattern by mistake, and other events that needed haptics like deleting a book had none. Also, the chapter-pull buzz was too faint to feel at all.
The real problem was that haptics had been added screen by screen, not by rule. So I set a rule for haptics too and added a labs section to test and pick the best haptics pattern.
A double buzz for every error: a failed download, a link that won't load, a book that can't open.
A single buzz for every destructive action or reset confirmation; this was built into the shared dialog so future dialogs get it automatically.
Error types with haptic feedback went 1 - 6. The chapter-pull buzz was too faint to feel, so I switched to a stronger 40ms buzz. Every error message now also says how to recover, not just what went wrong.
Lesson: consistency comes from rules built into shared components.


BENCHMARK NUMBERS
GLASS LAB CONTROLS FOR TUNING THE EFFECT APP-WIDE
An app that stored every book twice.
When I checked Frolickk in my phone’s settings, it was taking up 1.3 GB. My library was only about 45 books, and most of them already lived in a folder synced to the app. Frolickk was quietly making its own copy of every book, so each one was stored on my phone twice.
I redesigned it so books stay in one place: a normal folder the reader owns and can open in their file manager. Frolickk now reads books where they are and keeps only what it needs to be fast, like covers, the search index, and the reader’s highlights and progress. Because each book is recognised by its file rather than its name, renaming or moving a book never loses a highlight. If a file goes missing, the book waits for it instead of deleting the reader’s notes. Deleting a book now warns plainly that the file will leave the phone, not just the app.
After the one-time move, Frolickk went from 1.3 GB to 360 MB on my phone, about 72% smaller.
A Real Device is a Design Tool: My Figma files were careful, and the phone still didn't align with them about glass strength, icon cropping and status bar colours. I now treat on-device testing as part of designing, not as QA after it.
Rules beat one-off fixes: My best decisions weren't single fixes. They were the rules, like the distance rule and the haptics rule, that fixed a whole class of problems at once and keeps fixing them as the app grows.
Know which kind of problem you have: Working with Claude Code made engineering fast, which made my judgement the bottleneck. The most valuable skill was telling a code problem from a design problem. The flickering blur was a design problem dressed up as a code problem.
What I Learned




BEFORE & AFTER SCREENSHOTS OF THE APP INFORMATION SCREEN
The smaller fixes.
Small fixes also taught me the same thing: Figma and a phone are different places.
The app icon's wordmark was unreadable once Android cropped it. I redrew the icon with Android's safe zone in mind.
My phone runs in dark mode, so the status bar icons turned white on Frolickk's light mode screens and disappeared. They now follow the app's theme instead of the phone's.
For some reason typing random letters without a ".com" suffix in the input field for article links crashed the app. It now shows an error state instead for invalid links and keeps your text so you can fix it.
TITLE PILL'S MOTION AFTER I ADDED THE RULE

Frolickk - A Case Study on How I Built a Reading App with Claude Code
30th October, 2026
At a Glance
Role: Solo product designer
Type: Personal project
Built With: Figma for design, Claude Code for engineering (Kotlin & Jetpack Compose)
Timeline: 22 - 26 October 2026, 22 different versions and test builds
Status: Installable Android app (A.4.5). Not yet on the Play Store
TL;DR
I designed a reading app for EPUBs, PDFs and web articles, then built it with Claude Code. I designed every screen and decision; Claude Code wrote the code.
I tested every build on my own phone and logged 40+ issues. Some were bugs. Many were design problems that only showed up on a real device.
The biggest wins came from turning one-off fixes into app-wide rules for motion, haptics and errors.
A final speed & stability optimisation pass at the end cut launch database queries from 7 to 3 and made book libraries load about 2.5x faster in benchmark tests.
Download Frolickk
Download Frolickk and let me know what you think! A few things to keep in mind.
Frolickk is still in beta testing, so there is a chance you'd encounter bugs. Please email me or reach out on X if you spot any.
Frolickk isn't on the Play Store yet, so clicking on the download link redirects you to the Github repo and you'd have to side-load it from there.
Frolickk is only available on Android for now. (sorry iOS users)
Overview
Reading on my phone was a scattered experience. EPUB books lived in one app, PDFs in another, and articles stayed in browser tabs I hardly ever got back to. Wanting to read a book meant searching a website, downloading a file, then finding that file again in another app.
I wanted one calm place for all of it. So I set three goals:
One unified library for EPUBs, PDFs and web articles, with shelves that sort themselves.
No dead ends, I wanted to be able to pull an article with just a link or search a public library like Gutenberg, download a book, and start reading all without having to ever leave the app.
An app that felt premium and considered, a modern design with fluid motion, haptics and considered details.
There was a fourth, personal goal. I've designed products that developers built, but I'd never carried my own design all the way to a working app. I wanted to find out what breaks between a Figma frame and a phone in someone's hand.
FROM A PASTED LINK OR LIBRARY SEARCH TO READING WITHOUT LEAVING THE APP
Designing the System
I started in Figma with a small design system: Open Runde as the only typeface, a defined colour palette, and every component designed in its default, pressed, focused, error and disabled states. That last part paid off later. When a bug turned up in a text field, the fix was usually "use the state I already designed," not "invent something new."
Three things I did to give the app its character;
Glassmorphism. The nav bar, menus, sheets, and toasts all use a frosted glass effect with blur, refraction, an edge light and soft shadows. It's the most visible part of the brand, so it had to look right on a real screen, not just in Figma. Apart from being a really cool design style, I also chose it because I believe it's the most complex style (at least with regard to code) and I wanted to really push Claude to see what it could actually do.
Motion. Buttons depress slightly when pressed, sheets and menus grow out of the control that opened them, book covers zoom open into the page they lead to and shrink back when you leave. Everything moves on springs, and all of it can be turned off when someone turns on the "reduce animations" setting on their phone.
Haptics. I treated touch feedback as an important part of the design, not just a finishing touch. I picked each vibration from a labs section I asked Claude to add to specific test builds, on my own phone, rather than guessing from a spec sheet.
A few signature moments sit on top. Long-press a book and its cover lifts into a holographic card that tilts with your finger. The font size control is a drum dial with a buzz on every step.
How I Worked
I can't write Kotlin, so I split the work clearly. I owned the product: the designs, the decisions, the testing and the judgement of what "done" should look like. Claude Code owned the engineering: turning my Figma files into code, and debugging why something broke once I'd found it.
Every build went through the same loop:
Design the screen or fix in Figma.
Claude Code turns it into a test version of the app.
Test on my phone to find out what breaks: reading, searching, downloading, going offline on purpose.
Log what's wrong in plain words, the way a user would say it.
Decide on the fix. If the cause was a code bug, Claude Code fixed it. If the cause was a design decision, I went back to Figma.

EVERY ISSUE I FOUND WENT BACK EITHER TO CODE OR TO FIGMA.
That loop ran over 20 times between 22 and 26 October. It produced 40+ logged issues, 62 commits and 43 automated tests that stop fixed bugs from coming back.
Step 5 is where most of my design work actually happened. Over those iterations, I got better at telling a code problem from a design problem.
5 Problems I Encountered Worth Mentioning
Of the 40+ issues these 5 changed how I think about design.
LEFT TO RIGHT - BLUR VS FADE
The blur effect that made the whole app flicker.
In my design, book text faded softly under the status bar. The first build used a live blur to do it. On my phone, the whole page flickered as I scrolled, and it got worse when the word finder was open.
The cause was technical: the book page is a small built-in browser, and copying it every frame to blur it couldn't keep up. In a second iteration Claude moved the blur inside the page. That stopped the flicker but now it left a blurred patch that scrolled along with the text.
I stopped trying to get it to work with code. The blur wasn't what mattered to me; the soft edge effect was. So I went back to Figma and designed a plain white fade that gives the same feeling with nothing to compute. With this, nothing is drawn into the book page at all. Sheets that open over a book use a still snapshot of the page instead of a live blur.
Lesson: when an effect keeps fighting the platform, redesign the intent instead of patching the technique.
GLASS LAB CONTROLS FOR TUNING THE EFFECT APP-WIDE
Glass effects that looked right in Figma but off on my phone.
The nav bar used my exact Figma values, but on my phone it was way too see-through. Figma doesn't publish how its Frost setting maps to real blur strength, so the conversion came out roughly half as strong.
Instead of guessing values back and forth, I had a temporary Glass Lab built into the app: live sliders for frost, refraction, depth and light. I tuned the glass on my own screen until it looked right. (doubling Frost from 6 to 12 fixed the nav bar).
The lab also exposed a hidden bug. Glass blurred colours and covers fine, but text behind it stayed perfectly sharp at any setting. The fix applied to every glass surface in the app at once, not just the nav bar.
Lesson: some design decisions can only be made on the real device. When possible build a tool to make them there.
TITLE PILL'S MOTION AFTER I ADDED THE RULE
Motion that animated from the wrong place.
I wanted iOS-like motion: things should animate out of whatever you tapped. Once that was applied system-wide, a new problem appeared. Tapping the + at the top of Collections made a sheet animate from the top of the screen and travel all the way to the bottom which looked strange.
I turned that observation into a rule, which I call the distance rule:
Sheets always animate in from the bottom of the screen regardless of where the control is. The only exception to this is the reader's title pill which already sits at the bottom of the screen.
Dialogs animate from a nearby option, or simply appear in place.
Screens zoom out of book covers only if the cover is visible on screen. Otherwise they slide in from the left.
Lesson: a motion idea isn't complete until you've decided where it shouldn't apply.

SCREENSHOT OF THE LABS SECTION
Haptic feedback that was added screen by screen.
When I asked Claude for a list of every haptic in the app, I noticed certain gaps. Only one error, "Definition not found," had haptic feedback. Deleting a collection used that error's haptic pattern by mistake, and other events that needed haptics like deleting a book had none. Also, the chapter-pull buzz was too faint to feel at all.
The real problem was that haptics had been added screen by screen, not by rule. So I set a rule for haptics too and added a labs section to test and pick the best haptics pattern.
A double buzz for every error: a failed download, a link that won't load, a book that can't open.
A single buzz for every destructive action or reset confirmation; this was built into the shared dialog so future dialogs get it automatically.
Error types with haptic feedback went 1 - 6. The chapter-pull buzz was too faint to feel, so I switched to a stronger 40ms buzz. Every error message now also says how to recover, not just what went wrong.
Lesson: consistency comes from rules built into shared components.


BEFORE & AFTER SCREENSHOTS OF THE APP INFORMATION SCREEN
An app that stored every book twice.
When I checked Frolickk in my phone’s settings, it was taking up 1.3 GB. My library was only about 45 books, and most of them already lived in a folder synced to the app. Frolickk was quietly making its own copy of every book, so each one was stored on my phone twice.
I redesigned it so books stay in one place: a normal folder the reader owns and can open in their file manager. Frolickk now reads books where they are and keeps only what it needs to be fast, like covers, the search index, and the reader’s highlights and progress. Because each book is recognised by its file rather than its name, renaming or moving a book never loses a highlight. If a file goes missing, the book waits for it instead of deleting the reader’s notes. Deleting a book now warns plainly that the file will leave the phone, not just the app.
After the one-time move, Frolickk went from 1.3 GB to 360 MB on my phone, about 72% smaller.
The smaller fixes.
Small fixes also taught me the same thing: Figma and a phone are different places.
The app icon's wordmark was unreadable once Android cropped it. I redrew the icon with Android's safe zone in mind.
My phone runs in dark mode, so the status bar icons turned white on Frolickk's light mode screens and disappeared. They now follow the app's theme instead of the phone's.
For some reason typing random letters without a ".com" suffix in the input field for article links crashed the app. It now shows an error state instead for invalid links and keeps your text so you can fix it.
Results
In the final round, I fixed a lag I'd noticed: books sometimes took a moment to open, and my whole library took a moment to appear at launch and with my library being almost 1 GB in size I wanted the issue fixed. The answer was several small inefficiencies adding up, and fixing them made one of the biggest measurable differences of the project.

BENCHMARK NUMBERS
The benchmark timings were measured on a computer with the app's own database queries, not on my phone. A phone is slower overall, but the before-and-after ratio should hold.
The last row matters to me. Glass, springs, dials, floating download pills and a full speed pass together added just 63 KB to a 14 MB app. Polish doesn't have to cost the user anything.
Where the app stands currently: an installable Android app with over 10,000 lines of code, 43 automated tests and 62 commits, running on my phone.
What I Learned
A Real Device is a Design Tool: My Figma files were careful, and the phone still didn't align with them about glass strength, icon cropping and status bar colours. I now treat on-device testing as part of designing, not as QA after it.
Rules beat one-off fixes: My best decisions weren't single fixes. They were the rules, like the distance rule and the haptics rule, that fixed a whole class of problems at once and keeps fixing them as the app grows.
Know which kind of problem you have: Working with Claude Code made engineering fast, which made my judgement the bottleneck. The most valuable skill was telling a code problem from a design problem. The flickering blur was a design problem dressed up as a code problem.
