Frontend and product experience
Built editing interfaces with React and Next.js: timeline, clip manipulation, playback and export controls.

Over sixteen months, I worked across the different layers of Xnapper: editing interfaces, application logic and state, multimedia processing, persistence and backend services for a commercial product with approximately 20,000 users.
Visit XnapperXnapper is a commercial screenshot tool that expanded into image and video editing. As a Software Developer on the team, I owned features across the interface, application state, processing, persistence and service integrations — not a single layer of the stack.
The technical difficulty came from moving beyond static screenshot editing into frame-accurate video workflows that had to stay reliable and maintainable across different runtime environments, without sacrificing performance.
Built editing interfaces with React and Next.js: timeline, clip manipulation, playback and export controls.
Modeled editor state, undo/redo history and session/preset persistence, connecting interface behavior to the product's different workflows.
Implemented video processing with Node.js, FFmpeg and WebAssembly, coordinating files, playback, progress and output generation.
Designed and shipped a serverless licensing service that enforced per-device business rules and persisted activation state in Redis.
The product needed to move beyond static screenshot editing and support reliable video workflows without sacrificing performance, maintainability or consistency across environments.
The Electron application uses the Xnapper web app
Built this capability end to end: from timeline interactions and state modeling to frame extraction, processing and final export.
Designed and shipped a serverless backend to validate commercial licenses and control how many devices could be associated with each user.
Native video seeking wasn't reliable on variable-frame-rate footage — a seek could land on the wrong frame, breaking frame-accurate editing.
Extracted frames through a demuxer instead of relying on native seek, giving the editor a consistent, frame-accurate source regardless of a clip's original encoding.
Supporting multiple export targets was spreading conditional logic across the codebase, making every new export option riskier to add.
Introduced a shared export strategy interface so each target implements the same contract, keeping the branching logic in one place instead of scattered conditionals.
The client could validate the same license repeatedly, and an already-active device shouldn't duplicate its record or consume more than one available seat.
Designed activation as an idempotent operation: if the device was already active, the service returned success without duplicating the record. Deactivations were modeled with soft-delete to preserve history without consuming an available seat.