I Built a Full AI Directory From My Android Phone
A live Next.js and Supabase directory site, built and shipped entirely from an Android phone using Termux — real bugs included.
For the last several months I've been building ShabelleHub, a directory of AI tools with independent reviews, comparisons, and rankings. It's a Next.js app backed by Supabase, with a custom CMS, SEO structured data, an admin dashboard, and a design system I built from scratch.
I did all of it from an Android phone. No laptop. No desktop. Just Termux, GitHub's mobile web interface, and Chrome.
This isn't a gimmick post about "look what I can do on a phone." It's a record of the actual constraints, the actual bugs, and the actual workflow that let a phone-only setup produce a production Next.js site with a 96+ SEO score and steadily improving Lighthouse performance. If you're considering building something serious without a computer, this is what it really looks like.
Why phone-only, and why it's harder than it sounds
There's no IDE. No file tree you can drag things around in. No instant hot-reload preview sitting next to your code. Every change goes through a loop that looks like this:
- Write or edit a file in Termux (usually via
nano, sometimes by generating the whole file elsewhere and overwriting it withcp) git add,git commit,git push— with a Personal Access Token typed or pasted in by hand, every single time, because there's no credential helper configured- Open Chrome, go to GitHub, open a pull request
- Wait for Vercel's preview deployment
- Check the preview on a 6-inch screen
- Merge if it's good
That loop is slow. It also removes a lot of the safety net a desktop setup gives you for free — no local dev server running alongside your editor, no instant visual feedback. Every mistake costs you a full round trip.
The mistake that taught me the most: nano and autocorrect don't mix
Early on, I tried editing a package.json file directly in nano on my phone to add a new dependency. Android's keyboard autocorrect silently changed "browserslist" to "browserlist" — missing one letter — and mangled part of a multi-line array I was typing at the same time. The result was invalid JSON that I didn't catch until the build failed.
The fix wasn't "be more careful typing." It was stop typing structured code directly into a phone keyboard at all. Now, any time a file needs more than a one-line edit, I write the whole file's content in another context, package it as a small zip, and overwrite the file on-device with cp. Autocorrect can't touch a file that's copied byte-for-byte instead of typed.
This one workflow change eliminated an entire category of bugs.
The bug that took the longest to actually understand
The most instructive bug I hit was a search dropdown on the homepage that rendered behind the page's call-to-action buttons instead of in front of them. My first instinct was "just raise the z-index." I raised it to 9999. It didn't work.
The actual cause was CSS stacking contexts. I had wrapped both the search box and the CTA buttons in separate animated <div>s — first with Framer Motion, later with a pure-CSS @keyframes animation after I removed Framer Motion for performance reasons. Both approaches create the same problem: any element with an active opacity or transform animation establishes its own stacking context. Once that happens, a z-index set inside one animated div can only be compared against other elements *inside that same div* — it can no longer out-rank a sibling div elsewhere on the page, no matter how high the number is. Whichever sibling comes later in the DOM wins, regardless of z-index.
The real fix wasn't a bigger number. It was giving the search wrapper *itself* an explicit stacking context ranked above its sibling — position: relative; z-index: 5 on the wrapper, z-index: 1 on the CTA row. That's a completely different fix than "increase z-index," and I wouldn't have found it without actually reading how stacking contexts work rather than guessing.
Losing track of my own codebase
Because everything happens through a slow, manual pipeline, I ran a session in parallel using Claude Code that committed directly to main — removing Framer Motion for performance, self-hosting fonts, fixing a Largest Contentful Paint delay, adding a missing component. Good changes, all of them. But I didn't know about any of it until git log showed me commits I hadn't made, and a component I thought used Framer Motion turned out to be pure CSS.
The lesson: git log --oneline before you touch anything isn't optional when more than one thing might be changing your repository. I now check it as a reflex, the same way you'd check your mirrors before changing lanes.
What actually improved performance, and what didn't
I want to be honest about this part, because a lot of performance advice online is vague. Concretely, on this project:
- Adding a
browserslistfield topackage.json(targeting modern browsers only) did not change the "Legacy JavaScript" warning in Lighthouse. The polyfills were coming from inside a dependency's pre-built bundle, not from my own code — browserslist only affects how your *own* code gets compiled. - Self-hosting fonts via
next/fontand removing an external Google Fonts<link>tag measurably cut render-blocking time. - Enabling
experimental.optimizeCssinnext.config.js(which uses Critters to inline critical CSS) is a build-time change that doesn't touch a single line of component code, and directly targets "render-blocking requests" in the Lighthouse report.
Mobile Lighthouse performance moved from 68 to 83 over several rounds of this — not from one big rewrite, but from a series of small, verifiable, config-level changes, each one checked against a fresh PageSpeed Insights report rather than assumed.
If you're thinking about doing this yourself
A phone-only workflow won't make you faster. It will make you more deliberate, because every mistake is expensive to undo. If I had one piece of advice for someone attempting this: overwrite files wholesale instead of hand-editing them wherever you can, verify git status and git log obsessively, and never trust that a number like z-index is the actual problem just because it's the most visible one.
The site is live at shabellehub.com. It works. It's still being improved, phase by phase, from the same phone.
Frequently Asked Questions
Can you realistically build a production Next.js app without a laptop?
Yes — this site is proof, running on Supabase with a working admin CMS. It's slower than a desktop workflow because every change goes through a commit-push-PR-preview loop, but it's fully capable of shipping production code.
What's the biggest risk of editing code directly on a phone?
Keyboard autocorrect silently mangling structured text like JSON or multi-line code while you type it into an editor like nano. The safer pattern is generating full file contents elsewhere and overwriting the file on-device instead of hand-typing edits.
What tools are actually needed for phone-only Next.js development?
Termux (for git, node, and a terminal), a mobile browser for GitHub's pull request flow, and a deployment platform like Vercel that automatically builds preview deployments from pushed branches.
How do you preview UI changes without a local dev server visible alongside your editor?
By relying on Vercel's automatic preview deployments generated from each pull request — every branch gets its own live URL to check on the actual phone screen before merging.
📬 Get the latest AI tool reviews
Expert picks and comparisons, weekly. No spam.