Vishaal KarthikMobile Engineer · React Native
India ·

Vishaal Karthik, Mobile Engineer · React Native. I build mobile products and the systems behind them.

A great screen is the last 10% of the work. I spend my days on the other 90%.

Layers of a mobile product

Illustrative site-audit form. Forms like it log site visits for ≈400 field users every day.

02 Selected work

Work I’m proud of.

Seven pieces of one large enterprise React Native app: what I built, why it was hard, and what I decided.

performance.casePerformance

Rendering & offline storage

The slowdowns show up exactly where users spend the most time.

DecisionTreat jank as several causes, not one: recycle list views, read storage synchronously, compress images, and batch input on large forms.

FlashList virtualization, MMKV storage and image compression across the heavy screens: long lists, large forms, image-laden records.

performance.case

03 / Performance

Rendering & offline storage

The slowdowns show up exactly where users spend the most time.

Context

Screens on a configurable platform get big: long lists, many live fields, images attached to records. The slowdowns show up exactly where users spend the most time.

The problem

Jank and slow storage rarely have one cause. Lists re-create views, images arrive heavier than they’re displayed, storage reads block, and high-frequency events trigger more rendering than the screen needs.

Approach

  1. Adopt FlashList for long lists, recycling views instead of creating new ones.

  2. Move offline storage to MMKV for fast synchronous reads and writes.

  3. Compress images to reduce payload and memory.

  4. Batch updates and debounce high-frequency input on large forms.

  • FlashList
  • MMKV
  • Image compression
  • Batching
vapt-remediation.caseSecurity / OWASP Mobile

VAPT remediation

A VAPT report is a list of findings. Each one has to become a change that ships.

DecisionRemediation inside normal delivery rather than as a separate project, with behaviour verified after each change, because every fix carries regression risk.

Turning a third-party VAPT report and a long Dependabot queue into shipped fixes: WebView hardening, dependency upgrades, secure configuration.

VAPT findings remediated
16+
Dependabot alerts resolved
200+
vapt-remediation.case

04 / Security / OWASP Mobile

VAPT remediation

A VAPT report is a list of findings. Each one has to become a change that ships.

Context

VAPT findings arrive as reports. Someone has to turn each one into a change that ships, without breaking the features that depend on the code being changed.

The problem

Findings span very different layers: JavaScript libraries with known vulnerabilities, native configuration, WebView settings and transitive dependencies. Each fix carries regression risk.

Approach

  1. Map findings to OWASP Mobile Top 10 categories and use MobSF for static analysis of the app.

  2. Remediate vulnerable dependencies and verify behaviour after each change.

  3. Review and harden WebView configuration.

  4. Tighten configuration as part of normal delivery, not as a separate project.

What changed

  • 16+ third-party VAPT findings remediated.
  • 200+ Dependabot security alerts resolved.
  • OWASP Mobile Top 10
  • MobSF
  • WebView
  • Dependencies

16+ VAPT findings remediated

200+ Dependabot alerts resolved

location-field.caseProduct / Field workflows

Location field

An address is a label. The coordinates are the value.

DecisionCoordinates as the durable value over the address, because an address can be missing or stale; the address is only the label resolved from them.

A production location field for dynamic mobile forms: address search, raw coordinates, a fixed-centre map picker and explicit offline, read-only and disabled states.

field users logging site visits each day
≈400
location-field.case

07 / Product / Field workflows

Location field

An address is a label. The coordinates are the value.

Context

Field workers use the mobile form builder to record site visits. The location field is part of a dynamic, configuration-driven form renderer used by roughly 400 people each day.

The problem

A location can arrive as an address, coordinates or a GPS reading. Addresses can be missing or stale, maps can be disabled or offline, and read-only data must still remain useful.

Approach

  1. Treat coordinates as the durable value and the address as a resolved label; keep coordinates visible whenever a location exists.

  2. Support address search and raw coordinate entry in one full-screen picker, with a fixed centre reticle for precise map selection.

  3. Keep coordinate entry usable when the map is disabled or tiles are unavailable, and explain the state instead of showing a broken map.

  4. Distinguish read-only from disabled: preserve useful actions and provenance for submitted values, while disabled fields explain why they cannot be changed.

  5. Cache static map snapshots by rounded latitude, longitude, zoom and size so long forms do not mount a live map for every field.

What changed

  • Shipped as a production workflow used by roughly 400 field users to log site visits each day.
  • react-native-maps
  • Google Places
  • Geocoding
  • Offline states

≈400 field users logging site visits each day

Supporting case studyPlatform / React Native

The React Native upgrade, one hop at a time.

Moving a large production app from 0.77 to 0.86 in controlled hops, and onto the New Architecture (Fabric / Turbo Modules), without a long-lived branch or a production incident.

DecisionIntermediate hops over one large jump, because a single jump puts every incompatibility on the table at once with no way to tell which change broke what.

in intermediate, verified hops
0.77 → 0.86
migration-related production incidents
0
rn-upgrade.case

CS / Platform / React Native

React Native upgrade

Changing the version is one line. Everything that depends on it is the project.

Context

A large, long-lived React Native codebase behind an enterprise no-code / low-code platform. Staying on older versions accumulates platform debt: OS requirements move, libraries drop support, native toolchains change underneath you.

The problem

A single large jump puts every incompatibility on the table at once: dependencies, native builds on both platforms, and behaviour changes, with no clear way to tell which change broke what.

Approach

  1. Upgrade incrementally through intermediate versions, so each hop has a small, explainable blast radius.

  2. Map dependency compatibility before each hop; upgrade or replace the libraries that block it.

  3. Work through native build issues on both platforms: Gradle and CMake configuration, native modules that fail to compile or link, and iOS-specific build changes.

  4. Preserve the existing architecture: the upgrade changes the platform, not how the app is structured.

  5. Verify Android and iOS at every hop, so the codebase stays releasable instead of living on a long-running branch.

What changed

  • Moved from 0.77 to 0.86 through verified intermediate hops.
  • Migrated to the New Architecture with zero migration-related production incidents.
  • Existing architecture preserved through the migration.
  • Incremental hops
  • Dependencies
  • Native builds
  • Android & iOS
  • New Architecture

0.77 → 0.86 in intermediate, verified hops

0 migration-related production incidents

Read the write-up (opens in new tab)
areavN+1vN+2vN+3target
Dependencies✓✓✓
Android build✓✓✓
iOS build✓✓
Native modules✓✓
JS API changes✓✓
Architecture✓✓✓✓

$ upgrade target - done

✓ dependencies: peer dependency conflict

✓ android build: Gradle / CMake configuration

✓ js api changes: deprecated API usage

✓ architecture: behaviour drift check

Open issues
0
Releasable
Yes, every hop

Illustrative model of the strategy. Areas are real, counts are not.

  1. 01

    Incremental strategy

    Intermediate versions instead of one jump: build, run the critical flows, fix, then move on.

  2. 02

    Dependency compatibility

    A compatibility map before every hop; libraries upgraded or replaced when they blocked it.

  3. 03

    Native build failures

    Gradle, CMake and linking errors worked through hop by hop, not all at once.

  4. 04

    Android and iOS

    Two platforms moving at different speeds, both verified at every step.

  5. 05

    Native modules

    Modules that stopped compiling or linking under new versions and Turbo Modules.

  6. 06

    Release risk

    The app stayed releasable at every hop, never frozen behind the migration.

03 Experience

From features to ownership.

Jan 2023 - Present

Software Engineer

Workhall · Coimbatore

The iOS and Android app of an enterprise no-code / low-code platform, from one React Native codebase.

  1. 01 Features

    Shipping product features across iOS and Android.

  2. 02 Systems

    Building the reusable pieces other features stand on.

  3. 03 Architecture

    Shaping how the app is structured, built and released.

  4. 04 Ownership

    Code quality, security remediation, reviews and hiring.

Scope today

  • React Native development
  • Mobile architecture
  • Performance
  • Security / VAPT
  • Release engineering & OTA
  • Observability
  • Code & solution-design reviews
  • Technical interviewing
04 Credentials

Trained, and certified.

Education2019 - 2023

9.42/ 10 CGPA

Department Rank Holder

B.E. Mechatronics Engineering

Thiagarajar College of Engineering, Madurai

  • AWS Certified Cloud PractitionerAmazon Web Services· 2024
  • Microsoft Azure FundamentalsMicrosoftAZ-900· 2025
  • Oracle Generative AI ProfessionalOracle· 2025
  • Oracle Multicloud ArchitectOracle· 2025
  • Google Data Analytics Professional CertificateGoogle· 2021
  • Google IT Support Professional CertificateGoogle
05 Side projects

Projects & open source.

Some shipped, some still being built, one running live on this page. Drag the windows around.Swipe through the bench.

bench / 8 items
CLIaudit-rn - zshCLI tool

v0.1 shipped

audit-rn

OWASP-mapped static analysis CLI for React Native security.

  • Three AST-based checks: M1 hardcoded secrets, M8 insecure WebView, M9 sensitive keys in AsyncStorage.
  • Built with @babel/parser and @babel/traverse.
  • TypeScript
  • Babel AST
  • OWASP Mobile
  • CLI

npx audit-rn ./src

3 findings · OWASP Mobile Top 10

src/api/client.tsM1

// TODO: move to envconst API_KEY = 'a7f3c9e1b2d84f06';

AST VariableDeclarator › StringLiteral

A secret compiled into the JS bundle can be pulled out of any install.

Example output on sample files.

iOS · Androidkalibr.appSide project

In development

Kalibr

A calm daily perception calibration app: 90 seconds a day.

  • Results shown as levels of blur, not scores. No leaderboards.
  • Randomised micro-tests (reaction, colour discrimination, focus, memory, contrast, wide focus) on a seeded RNG, so everyone shares the daily challenge.
  • Scored against your own baseline, not raw numbers: “Perception Weather”, from Sharp to Foggy.
  • A 30-day Fingerprint with drift detection.
  • React Native
  • Skia
  • Reanimated
Day 12+5%vs. your baseline

30-day Fingerprint · sample data · drag to scrub

iOS · Androidbloom.appSide project

In final development

Bloom

A privacy-first menstrual health tracker.

  • All processing on-device, no cloud accounts. Sensitive data stays local by design.
  • Cycle prediction, symptom and mood tracking, personalised insights.
  • React Native
  • Expo
  • On-device storage
Webrecycler.demoLive demo

Cell recycling, visualised

How FlashList-style lists stay fast: a thousand items, a handful of views. The badges are real. React reuses the same DOM nodes as you scroll.

  • Virtualization
  • Recycling
  • Performance
view 1Item #1
view 2Item #2
view 3Item #3
view 4Item #4
view 5Item #5
view 6Item #6
view 7Item #7
view 8Item #8
view 9Item #9
view 10Item #10
Items
1,000
Views mounted
10
Rebinds
0

Scroll the listScroll the page to move the list

Desktopnook - desktopSide project

Concept / early build

Nook

A desktop companion that gets you to take real breaks.

  • An animated avatar companion that lives near the taskbar.
  • Cinematic fullscreen break overlays and guided break activities.
  • Plant/pet gamification, ambient time-of-day and weather effects, rich sound design.
  • Spring animations and a calm palette.
  • Tauri 2
  • React
  • Desktop (Windows / macOS / Linux)
Weborbis - webSide project

Orbis

An interactive geography learning platform built around a 3D globe.

  • React
  • Three.js
Webhearth.appSide project

Hearth

A calendar for families, teams and friends: recurring events, drag-to-reschedule and an avatar showing who added each event.

  • React 19
  • TypeScript
  • Supabase
  • Also builtYouTube Educational FilterA Manifest V3 Chrome extension that filters YouTube down to educational and useful content.Chrome MV3 · JavaScript

06 / WritingCurated here · 10 in the archive

Writing

Notes on mobile engineering, with the occasional detour into AI. Published on Medium and in Stackademic, JavaScript in Plain English, AI in Plain English and Developers Global.

Follow on Medium (opens in new tab)

FeaturedEngineering / React Native

What 3 Years of React Native Taught Me That the Docs Never Will

OEM quirks, native modules, 16KB page sizes and locale-specific date crashes. Lessons from shipping production apps.

Three and a half years ago, I read the React Native docs top to bottom and thought I understood mobile development. I didn’t. What actually matters only reveals itself after your first production crash at 2 AM, your first furious enterprise client, and your first week debugging an issue that turned out to be a Samsung-specific OEM override.

17 May 20269 min readPublished in Stackademic

Read the article

07 / Contact

Have something worth building?

Open to conversations about mobile architecture and React Native work.