Read before you rewrite
Unfamiliar code usually has a reason for the way it behaves. I trace that reason before touching anything — it's the slow half of a migration, and the half that decides whether it works.

About
Frontend engineer with 4+ years building production web applications in React, Next.js, and TypeScript. Most of my work is on the parts that decide whether an interface stays good over time — shared component libraries, typed data layers, render performance, and tests worth trusting.
I'm a frontend engineer, four years in. What I care about most is the architecture underneath a UI — where state lives, what a component's API actually promises, and how much the tenth feature costs compared to the first.
Most of that I learned maintaining a shared component library behind four production applications. Building a component once is easy; building one that several teams can use without forking it teaches you what a good API actually costs. The same goes for the data layer — I own the typed REST integration across those apps, so loading, error, and empty states are defined once instead of reinvented per screen. Consistent failure states are part of what makes software feel trustworthy.
The most useful lesson came from migrating a dozen-odd legacy pages to React and TypeScript. The hard part was working out why the existing code behaved the way it did — tracing dependencies through an undocumented codebase, understanding decisions made by people who had long since left, and judging when to preserve behaviour rather than replace it. Writing the React was the easy part by comparison.
I came into frontend through Laravel and backend work, which still gives me a better read on the systems behind the interfaces I build. These days I also mentor two junior developers, which has made me better at explaining a decision than just making it.
I'm based in Kochi and open to senior frontend roles, in India or with remote-first teams. If you're building something where the interface has to carry real weight, I'd like to hear about it.
How I work
Unfamiliar code usually has a reason for the way it behaves. I trace that reason before touching anything — it's the slow half of a migration, and the half that decides whether it works.
A component copied into each app drifts from itself over time. A shared layer is what keeps a growing product feeling like one product.
Loading, error, and empty make up most of what a real interface actually shows. The happy path is the easy 20% — and rarely the part that breaks.
Speed is unglamorous: less JavaScript shipped, more rendered on the server by default, and performance measured on the hardware people actually use — not a developer laptop.
Where I go deep
Shared libraries, design tokens, and component APIs that hold up when more than one team is building on them.
Where state lives, and what a typed fetching layer hands a component — with loading, error, and empty states defined once rather than per screen.
Bundle budgets, render cost, and the page-load work that turns a slow screen into one people actually use.
React Testing Library, Playwright, and Vitest, plus cross-browser checks — coverage that mirrors real use, so refactoring stays routine.
Full role history with what shipped, education, and the complete stack.