Open to senior engineering roles
One engineer.
Every layer.
Full-stack and platform engineer. Eight years taking products from a blank plan to a running service, with interfaces people feel the quality of, and the numbers to prove it. In teams at X5 Group and SberEducation, on products at up to 7.5M monthly users. On my own, Tuned, a resume SaaS from first commit to payments in five weeks. And the original author of nestjs-zod, at 5.5M installs a month.

Looking for the next team
Open to senior engineering roles — remote worldwide as a contractor or through an employer of record, or hybrid in Yerevan. I work best owning a feature end to end, from the screen someone touches to the services behind it, alongside engineers who hold each other to a high bar. How fast and how clearly that screen answers is part of the feature. Contract work and one-off architecture reviews too.
updated 2026-10-04
lately
- nowBuilding Tuned, my own product, live with payments — resume tailoring where every variant is a patch over one base document rather than a copy.
- nowShipping Frame Player — a 4K HDR file cast to a television with no re-encode, on Windows and macOS.
- nowKeeping dubsync and DeskVolt alive — an audio-sync tool and a battery widget for wireless peripherals.
- 2024–2026Senior full-stack engineer at X5 Group, Russia’s largest food retailer — SSR Next.js and a BFF over FastAPI services for a recipe platform at 7.5M monthly active users: mobile pages 15–25 Lighthouse points faster, a third less JavaScript, cached pages in 100–200 ms instead of a 700–800 ms render.
- 2025Launched Gift Fight, a real-time PvP Telegram game, to about 1,500 players. Later closed it on the funnel data rather than carrying it on; the cluster and the code are still the work.
- 2024Handed nestjs-zod to a new maintainer. Still the ecosystem default at 5.5M installs a month.
- 2023Sole engineer on Sigma Games, built with a business partner — an iGaming product built from scratch end to end: ten ASP.NET Core services for payments, wallets, affiliate, gaming and auth, a React Telegram Mini App for players, an admin panel for operators, and the Kubernetes cluster it ran on.
- 2022–2024Full-stack at SberEducation — NestJS services over RabbitMQ, BFF contracts that stopped upstream changes reaching clients, schema-driven client generation in CI, and an accessibility-first payment widget at Lighthouse Accessibility 95+, with keyboard and focus behaving the same on every paid path.
- 2021A shared UI kit at Haiku Dev that four product teams adopted, and @cardbox/editor shipped as a published library — a Slate-based WYSIWYG, sole engineer on it.
- 2018Went freelance full time and started dealing with the client directly: scope, deploy, and the support after launch. Where the eight years start.
How I draw a system before any of it exists
Every product below is a subset of this, sized to the problem. Six steps take each one from a plan to a running service, whether it ships to a cluster or to an installer.
01 spec
Acceptance cases first. Written down before implementation starts. It is what a reviewer checks the work against, and what an agent is held to.
02 contracts
Types at every seam. One schema serves validation, types and the generated docs, so both sides of a seam can be built in parallel and a broken state is impossible to express.
03 ci gates
Tested against the real thing. Unit, integration and contract tests, Testcontainers against real PostgreSQL, Redis and NATS. Security and performance are gates, not follow-ups.
04 delivery
GitOps, not hands. FluxCD reconciles the cluster to the repository. Releases and rollbacks are the same operation, and both finish in under three minutes.
05 platform
Written down, not clicked. Kubernetes on Talos Linux across bare metal and cloud, described in one Pulumi program that anyone on the team can read and change.
06 operation
I hear about it first. Metrics, traces and structured logs on every service, and enough signal to know something is wrong before a user reports it.
runtime/ one request from edge to storage
Drag the figure sideways to follow the path
Selected work
Each taken from a blank plan to production, with a link to the source wherever the source is public.
Tuned
Resume tailoring where every variant is a patch over one base document rather than a copy, so a hundred applications stay one source of truth, and nothing silently drifts.
- A provenance check refuses any claim that doesn't trace back to a source node, so the model can rewrite but cannot invent.
- The live preview renders the same react-pdf component inside a Web Worker and rasterises it with pdf.js, so page fitting is measured against a real renderer instead of estimated.
- TypeScript
- React 19
- pdf.js
- Bun
- Elysia
- oRPC
- PostgreSQL
- Drizzle
- BullMQ
- Kubernetes
Frame Player
Casts a 4K HDR file to a television exactly as it is: no re-encode, no quality loss, and the app window stays a working remote. Torrents play while they are still downloading.
- mpv renders into a native child view behind a transparent webview, the whole UI composited on top as HTML. On macOS that meant patching libmpv, whose backend has no window-embedding support at all.
- Hover previews sharpen to the exact frame under the cursor. Naive keyframe mapping showed the wrong scene 60% of the time, so the cost of an exact seek is probed per file.
- 2 platforms
- signed, auto-updated by CI
- 0 re-encodes
- on a 4K HDR cast
- 60% 0
- wrong-frame previews
- Rust
- Tauri 2
- Svelte 5
- TypeScript
- FFmpeg
- libmpv
- Chromecast / DLNA
Gift Fight
A PvP roulette where players bet collectible Telegram gifts against each other, and every round can be recomputed afterwards by anyone who played it. Architected, built and operated end to end.
- A round in progress lives in a Temporal workflow rather than in a server's memory, so a restart or a release never drops it.
- Live play runs over Socket.IO beside ordinary HTTP, with blockchain payments isolated behind transfer services and idempotent settlement.
- 120 ms
- p95 state sync, 300 sessions
- every round
- survives a deploy
- ~1,500
- players at launch
Shut down in 2025, on purpose: the funnel showed free channels bringing non-paying users, so the product was closed on the data rather than carried on. The cluster and the code are still the work.
- TypeScript
- React
- Hono
- PostgreSQL
- Temporal
- Socket.IO
- Kubernetes
- Pulumi
dubsync
The 4K release ships only the original audio, and the dub you want exists on an old rip that is cut and timed differently. dubsync finds the offset by itself and produces one file with both.
- The soundtracks are correlated with GCC-PHAT and every result carries a peak-to-sidelobe score, so a bad match is reported rather than silently shipped.
- Differently cut releases are aligned segment by segment to about 50 ms, frame rates normalised, audio time-stretched instead of clipped, subtitles shifted to match.
- The shared anchor track is correlated once into a piecewise offset map that every selected dub reuses, and each splice is snapped to a moment the master is silent, so the cut hides behind a quiet scene change.
- ±50 ms
- per-segment alignment
- scored
- every result, never guessed
- 3 modes
- GUI, CLI, headless
- 1 pass
- one correlation serves every dub
- Rust
- FFmpeg
- egui
- FFT / GCC-PHAT
- Matroska
Shipped and operated
Tools I have run in production, not ones I have read about.
Chosen per constraint rather than per fashion.
frontend/
- TypeScript
- React
- Next.js
- Svelte 5
- Astro
- Tailwind
- Effector
- TanStack
- Core Web Vitals
- WCAG
- Design systems
backend-and-data/
- .NET 9
- Node.js
- Bun
- Hono
- Elysia
- PostgreSQL
- ClickHouse
- Redis
- NATS
- RabbitMQ
- Temporal
- EF Core
- OpenAPI
platform-and-ops/
- Kubernetes
- Talos Linux
- Docker
- Pulumi
- Terraform
- Ansible
- FluxCD
- Cloudflare
- Hetzner
- DigitalOcean
- GCP
- Prometheus
- Grafana
- Sentry
- Actions
further-afield/
- Rust
- Tauri 2
- FFmpeg
- WebAssembly
- Win32 / Direct2D
- USB HID
- libmpv
- Audio DSP / FFT
- HDR / Dolby Vision
- Applied cryptography
- Telegram Mini Apps
Open source
Two libraries other people's projects depend on.
I wrote both; one is now in another maintainer's hands.
nestjs-zod
- installs a month
- 5.5M
- stars
- 1.1k
The standard way to use Zod with NestJS: one schema serves validation, TypeScript types and the generated OpenAPI docs, so the same data is never described twice. Written by me and transferred to another maintainer in 2024, still the ecosystem default.
eslint-kit
- stars
- 130
- status
- archived
Preset-based ESLint configuration: one short config instead of the usual sprawl of plugins, parsers and rules, across very different frontend and backend stacks. Archived: Biome now covers the same ground in one binary.
Write to me
Senior product, full-stack or platform roles, contract work, and one-off architecture reviews. The terms are up at Looking for the next team.
Yerevan, UTC+4remote worldwide, contractor or through an employer of recordEnglish (full professional), Russian

