Thumbnail

QLock - MCQ Timer App

How it started

one day I was talking with my roommate and i asked him hows his study going he said hes using an spp for timed questions so he can record how much time is taken for each question, he's a GATE aspirant. he was also saying that most of the apps lack basic features or the UX is painful to use when you're trying to simulate real exam conditions.

I was like — wait, I can build this.

so we sat down, brainstormed features, discussed what he actually needed vs what existing apps were giving him. and that's how QLock was born. he was basically my user 0, my first real client. we're still adding features to it honestly, the list keeps growing.

What it does

QLock is built for students appearing for JEE, NEET, GATE and other competitive exams where time management is everything. it supports MCQ, MSQ, and NAT question types — because different exams use different formats and most apps just ignore that.

you can set timers per question or for the entire session, practice under real exam pressure, and track how you're doing over time. the whole point is to make practice feel like the real thing.

The tech stack

Technology Purpose
React Web Frontend
React Native Mobile App (Android)
Rust / Axum Backend API
Expo Mobile Tooling

The jetpack compose disaster

The first mistake i did was making the webapp first and then going on to make the mobile app

so when I decided to build the mobile app, I wanted a pixel-to-pixel clone of the web version. so naturally I asked claude — "hey I want to make an exact clone of my web app for android, what should I use?"

claude said jetpack compose.

so I blindly followed it. started building in kotlin, jetpack compose, the whole android native setup. and oh man, it was a nightmare. trying to replicate a React web UI in jetpack compose is like trying to write a novel in a language you barely speak. the paradigms are completely different, the styling system is nothing like CSS, and I was spending more time fighting the framework than actually building features.

after a few painful days I stepped back and thought — wait, why am I doing this to myself? I already know React. the web app is in React. why not just use React Native?

switched to React Native with Expo and things immediately clicked. the component structure was familiar, I could reuse a lot of the logic, and the styling was close enough to CSS that I wasn't losing my mind anymore. lesson learned — don't blindly follow AI suggestions without thinking about your own context first.

Why Rust for the backend

I could've just used express and called it a day. but I wanted to learn Rust, and building a real project is the best way to do that. Axum turned out to be a great choice — it's fast, the type system catches bugs at compile time, and honestly once you get past the borrow checker it's pretty satisfying to write.

Where we're at now

the web version is live and working. the android app is built and functional — we're holding off on publishing to the Play Store until we finish a security audit. I don't want to ship something to real users without making sure auth, data handling, and all that stuff is solid.

we still have a bunch of features on the roadmap that my roommate and I keep brainstorming. it's one of those projects that just keeps evolving because we're actually using it.

What I learned

  • build for a real user. having my roommate as user 0 made every feature decision easier. no guessing, just "does this actually help him practice better?"
  • don't blindly follow AI. claude is great but it doesn't know your context. jetpack compose was the "correct" answer technically, but react native was the right answer for me.
  • Rust is worth the pain. the learning curve is steep but once it clicks, you write more confident code.
  • cross-platform is hard but doable. porting from React to React Native isn't a copy-paste job, but the mental model transfers really well.

Comments