JWT Decoder
v1.0.0Decode, inspect and actually verify JSON Web Tokens — entirely on the device, with no token ever leaving the phone.
Flutter · Android · Based in the UAE
I'm Muhammad Taha — a Flutter and Android developer based in the UAE. Fifteen of my apps are on Google Play. They're single-purpose utilities that share one toolchain, one services layer and one rule: if a feature isn't tested and translated, it isn't done.
Nine are written up below — each with the engineering decision inside it that turned out to matter more than the feature list. The rest are listed underneath.
Selected work
Flutter, Android-first, offline by default. Each card notes the version, the test count, and the part that was genuinely hard. Six are live on Google Play; three are finished and waiting on a release.
Decode, inspect and actually verify JSON Web Tokens — entirely on the device, with no token ever leaving the phone.
Format, validate and explore JSON — without silently rewriting the document you pasted in.
json.decode. Dart's built-in parser
changes data: 1e5 becomes 100000.0, 1.50 becomes
1.5, huge integers lose digits and duplicate keys vanish. So this ships a
hand-written recursive-descent scanner that carries every number as literal text,
keeps duplicate keys and reports them, and returns error codes with line and
column — because the messages exist in ten languages.
Digests for text and for files, with a searchable history you can undo.
HashEngine testable
while the app around it grew a file picker, an undoable history, a GDPR consent flow
and push topics — a 1,034-line main.dart split into 33 files without
changing a single digest.
Qibla direction, prayer times, manual location and a map — accurate without a network connection.
HeadingPlugin in Kotlin and Swift: Android's
GeomagneticField declination (true north with no bundled magnetic model and
no network) and the raw magnetometer accuracy bucket, so the app can tell you when to
recalibrate instead of quietly pointing the wrong way.
Upside-down, mirrored and scrambled Unicode text in fifteen styles.
Screen size against viewing distance — metric and imperial, viewing angle, real screen dimensions and a scaled room diagram.
Spot the one tile whose shade is different, against the clock, with a daily challenge.
Repeat text by count or by target length, with custom separators, escape sequences and file export.
AmountMode, not RepeatMode, because Flutter's material library
already exports that name and the ambiguity is silent.
Open a WhatsApp chat with any number without saving it to your contacts first.
+971 50 123 4567 back-to-front unless the number is isolated.
Also on Google Play
Nine more published utilities, same toolchain, same release checks. Smaller in scope than the nine above, so they get a line each rather than a write-up.
All fifteen live listings are on my Google Play developer page.
How these get built
The apps are unrelated, but they are not built differently. A single reference implementation — Income Tax Calculator — carries the services layer, the Gradle config and the release checks; each new app copies it rather than reinventing it.
models/ services/ screens/ widgets/ theme/ utils/ — no app keeps logic in main.dart. Business rules live in pure Dart services that can be tested without a widget tree.
1,300+ unit and widget tests across the nine apps above — and a manual pass on hardware regardless, because clipped layouts, font scaling and time zones stay green in CI right up until a user sees them.
Up to fifteen locales including Arabic and Urdu, so RTL and bidi are design constraints from the first screen instead of a bug report after launch.
tool/check.sh plus a 16 KB page-size check on every release build, so Android's alignment requirement is verified before upload rather than discovered during review.
Three of these apps replaced a popular package with their own implementation — a JSON parser, a compass plugin, a flip table — because the convenient option was quietly wrong.
Hashing, JWT verification, prayer times and Qibla bearing all resolve on-device. Nothing a user types is sent anywhere to be processed.
Toolchain
Current shared baseline, kept in lockstep across the family so a fix in one app ports to the rest.
# framework flutter 3.47 # dart 3.13 languages Dart, Kotlin, Swift # android gradle 9.1.0 # agp 9.0.1, kotlin 2.3.20 sdk compile/target 36, min 24 jvm 17 # platform services firebase core, analytics, crashlytics, messaging local flutter_local_notifications, shared_prefs ads google_mobile_ads + UMP consent # quality tests unit, widget, integration, on-device AOT lints flutter_lints 6 checks tool/check.sh, check_16kb.sh, check_l10n.py
Flutter and Android work — new apps, or rescuing one that has drifted a few toolchain versions behind. Email is the fastest way to reach me.