Inspiration

I got my motorcycle licence in Taiwan and the exam was never the hard part. The hard part was everything around it. Nobody tells you that the booking closes at midnight two days before the test, so the day before is already too late. Nobody tells you that the hazard perception test is a hard gate and the system silently refuses your booking until the result is on your record. Nobody tells you that if you tick 輕型 instead of 普通重型機車 on the form you get a licence capped at 50cc and find out much later. Nobody tells you the driving school is optional, which is about NT$12,000 you do not have to spend.

The thing that pushed me to build it is a detail people get wrong. Taiwan's government did translate the exam. The official question bank is published in eight languages, so the usual complaint that "it is only in Mandarin" is simply false. What happened is that they translated the questions and stopped there. The theory manual that explains why an answer is right exists only in Traditional Chinese. The process around the exam exists only in Traditional Chinese. So a migrant worker from Vietnam or Myanmar can read the question in their language and still fail, or worse, never reach the exam at all because a step nobody wrote down in their language blocked the booking.

That gap is the whole product. Roughly 800,000 migrant workers live in Taiwan and a scooter is not a hobby for most of them, it is how you get to a factory at 6am.

What it does

The bank. All 2,172 official questions, parsed straight from the Highway Bureau's own PDFs. Car (1,090), motorcycle (804), road signs (152) and hazard perception (126). Practice by the government's own category tree, mock exams with the real format and pass mark, wrong answer review, bookmarks and history.

The 126 hazard videos, offline. These gate the motorcycle booking and the official bank links them as a Synology share page, which no video player can open. I downloaded them once, re-encoded 640 MB down to 57 MB and bundled them, so they play with no signal and no data cost.

The 347 sign graphics, redrawn. The exam prints its signs at a couple of centimetres and the PDFs store them squashed, so round signs come out as ellipses. I fixed the shapes against the set's own statistics and redrew 88 of them from the sharpest copy across the four files.

The guide. The step by step journey of the real process, in eight languages, which is the half nobody else has. Fees, documents, where to book, what gates what, the 120 minute safety talk that you must sit before you can even register, the ten items the riding examiner actually scores and the fact that a single deduction of 32 points out of 100 is already a fail.

The podcast. 144 narrated episodes, eighteen per language across eight languages, so the theory can be studied with hands on the handlebars. Served from Cloudflare R2, free to listen, no app install needed.

How I built it

The app is Expo and React Native with expo-router and TypeScript, one codebase for iOS, Android and web. The design system is the moat, since the competing apps have decent content and hostile interfaces.

The dataset is a reproducible Python pipeline over the four official PDFs, pdfplumber and pypdfium2 for parsing and rendering, with separate passes that reshape the distorted signs, upscale from the sharpest available copy and trim the table borders the PDF crops carry. Every regeneration is a command, not a manual edit.

Monetization is RevenueCat driving a one-time purchase that removes ads for good, plus Restore. Deliberately no subscription. A driving licence is a terminal goal, you pass and you leave, so a subscription would fight the nature of the product. Ads are AdMob, a banner plus capped interstitials, and they are wired out of the two moments that wreck the reviews of every rival app, never before an exam score and never in the review, wrong answer or bookmark sections.

OneSignal covers the one thing the phone cannot know on its own, which is the government changing a rule. A scheduled script watches eleven official pages every week and reports what moved, and only then does a broadcast get written by hand, one request per language because OneSignal's own language list does not include Burmese or Khmer and would have silently dropped two of my core communities into English. The exam countdown is the opposite case and runs locally on the device, because the whole point is reaching someone who has not opened the app in weeks.

There is also an Astro marketing site with the guide content extracted from the app so there is one source of truth, and a Cloudflare Worker behind the in-app report form that writes to D1 and sends one alert mail.

Challenges I ran into

The government's own text is broken. In Thai, Burmese and Khmer, the official PDFs put vowel and medial marks before the consonant they attach to, so the text extracts in an order those scripts cannot render. I assumed my parser was at fault and spent a long time proving otherwise. The official online mock exam has the same defect in its own Burmese page title. And in Vietnamese, 83 questions ship with the machine translator's introduction still attached, the literal sentence "This is a professional translation of the motorcycle written exam question into Vietnamese", inside the published government file. So one of the eight official editions is an unreviewed LLM output.

Android nearly cost me the deadline twice. Expo's template signs the release build with the debug key and Gradle says nothing, so the AAB looks fine and Play rejects it on upload. And one minor version bump of the ads SDK pulled in a library compiled with Kotlin 2.3 while Expo compiles with 2.1, which kills the build half an hour in with a message that names neither. It is pinned to an exact version now.

The paperwork was harder than the code. Verifying an AdMob account from Taiwan needs a US phone number. Apple's paid apps agreement needed a tax form decision for a foreign-owned LLC. Google Play's twelve testers for fourteen consecutive days is the only deadline in this project that cannot be recovered by working harder.

Accomplishments that I'm proud of

Every factual claim in the app is traced to an official source and dated, and several of them contradict what the English-language guides say. The motorcycle riding test scores ten items, not the five that every expat blog repeats. The safety talk is 120 minutes and gates registration, not exam day. The car's narrow-lane turnaround is not tested for an ordinary small car at all. I checked the government's own scoring sheets published in the official gazette rather than trusting first-hand accounts, including my own, and I had to correct my own notes three times.

Also, the whole thing is legal to ship. Taiwan's Copyright Act Article 9(5) says exam questions held under law carry no copyright at all, which is why the bank can be shipped, translated and recited freely.

What I learned

That the accessibility problem is almost never the thing that gets budgeted. Translating 2,172 questions into eight languages is expensive and visible, and it was done. Writing down that the booking closes at midnight two days before is free and invisible, and it was not. The second one is what makes people fail.

And that building in public changes the product. I asked publicly which of two screenshot sets to use, the hand-built ones or the AI-generated ones, and the answer was not the one I expected. The hand-built set won.

What's next

Native review of the six machine-translated locales, a converter for the broken Thai, Burmese and Khmer text, and plain-language explanations of why each answer is right, generated once per question and shipped as static data so they cost nothing per user and work offline. That last one is the manual the government never translated, rebuilt from the questions it did.

Built With

Share this project:

Updates

Submission history