Full-stack developer and AI integrator, working mostly in TypeScript — Node.js services and APIs on the back end, Vue 3 on the front, and LLM pipelines wired into products rather than bolted on afterwards: embeddings and deduplication, classification, rewriting and translation, with the orchestration and the guardrails around them.
My open-source time goes somewhere much narrower: Vapor mode in vuejs/core — finding the
places where a Vapor component and its VDOM equivalent disagree, and closing the gap.
name: "Valentin Youshkevich"
handle: ValentinYoushkevich
focus:
- "Full-stack TypeScript — Node.js, Fastify, Express, Prisma / PostgreSQL"
- "Vue 3 · Vite · Tailwind on the client"
- "AI integrations — LLM pipelines, embeddings, local and hosted models"
open_source: "Vue ecosystem — core (Vapor mode), eslint-plugin-vue, vueuse, vite, element-plus"
house_rules:
- "A failing test before the fix, always"
- "Smallest sufficient change — no drive-by cleanup"
- "If it claims a perf win, it ships with numbers"Vapor mode is meant to be behaviourally identical to the VDOM renderer. I run the same component tree through both renderers and diff the result — DOM shape, prop values, hook order, hydration mismatches. Where the two disagree, one of them is wrong, and that disagreement becomes a failing test before it becomes a patch.
Merged — 64 pull requests in vuejs/core, all in Vapor mode:
| Area | What I fixed | PRs |
|---|---|---|
runtime-vapor — KeepAlive |
A cached VDOM child kept stale props; a component reactivated in a nested branch never unmounted; an include/exclude change dropped the current branch |
#15560, #15526, #15525 |
runtime-vapor — hydration |
Multi-root async components desynced the walk; empty text blocks were hydrated out of place; a null value binding crashed |
#15532, #15534, #15541 |
runtime-vapor — VDOM interop |
Nested VDOM content was not unmounted; a VDOM child rooted at a slot outlet resolved to the wrong nodes; slots never reached VDOM async components; a dynamic component remounted same-type vnodes instead of patching them; $el and other $ properties broke on exposed Vapor instances read from VDOM refs |
#15524, #15542, #15513, #15631, #15624 |
runtime-vapor — rendering |
v-for item order broke around empty nested branches; transition classes were wiped by a class update; deferred teleport children fired update hooks on mount; bound checked / selected were not mirrored to attributes, so a form reset undid them |
#15529, #15528, #15527, #15636 |
compiler-vapor — expressions |
Repeated expressions were replaced by text match instead of AST range; optional-chain prefixes and member expressions with unsupported keys were cached unsafely | #15538, #15530, #15540 |
compiler-vapor — output parity |
Raw values lost on v-model; number literals lost on slot outlet props; the leading newline of <pre> / <textarea> dropped; key wrongly honoured on <template> branches; static attribute values and comments decoded twice; nullish dynamic v-bind arguments were rendered instead of dropped |
#15553, #15539, #15543, #15514, #15509, #15563, #15620 |
Also merged: #15721, #15720, #15719, #15714, #15713, #15709, #15707, #15706, #15705, #15698, #15669, #15667, #15666, #15665, #15664, #15657, #15656, #15655, #15654, #15647, #15646, #15623, #15621, #15606, #15601, #15594, #15588, #15587, #15583, #15575, #15574, #15552, #15550, #15522, #15520, #15511, #15510, #15506, #15497 in vuejs/core, plus language-tools#6214, eslint-plugin-vue#3143, eslint-plugin-vue#3122, typescript-eslint#12697, eslint-plugin-vue#3116, eslint-plugin-vue#3115 and eslint-plugin-vue#3113.
In review — open pull requests in
eslint-plugin-vue (13),
vuejs/core (12),
element-plus (4),
vite (3),
vueuse (2) and
language-tools (1),
including four new eslint-plugin-vue rules.
| Project | What it is | Stack |
|---|---|---|
| clever-vibe | Tracks where AI assistants actually help in development: each use is logged in 20–30 seconds against a catalogue of ~41 approaches, scored for usefulness and trust, and rolled up into frequency × usefulness quadrants, stage coverage and per-approach spread — with averages muted below N = 5. | TypeScript · Fastify · Prisma/PostgreSQL · Vue 3 · PrimeVue · Vitest · Docker |
| news-poster | News pipeline for Telegram channels: RSS collection, embedding-based deduplication, local bucket classification, LLM rewrite and translation, preview and publishing from a Vue 3 admin panel. | TypeScript · Express · Prisma/PostgreSQL · Vue 3 · Ollama · OpenRouter · n8n · Docker |
| palisad | Offline-first PWA for plant nurseries: a QR-tagged plant registry, field operations log, movements and printable PDF labels — the whole workflow runs with no connection and reconciles when one returns. | Vue 3 · Dexie/IndexedDB · Workbox · Express 5 · PostgreSQL · Knex · pdfkit |
| cleverlog | Employee time-tracking system — per-project logging, roles, and validation rules, built from a written spec. | JavaScript · Node.js · Vue |
| patientDataCollector | Chrome/Edge extension (Manifest V3) that collects patient referral fields straight from EMR pages, lets the missing ones be filled in by hand, attaches saved provider data and posts the result as JSON to a configured endpoint. | JavaScript · Vue · Manifest V3 |

