Projects

Personal and open-source projects — all of them live, all of them you can open and play with right now. Client work is under NDA, so I don't cover it here.

RRRabota

RRRabota

Mass hiring runs into a simple problem: an applicant searches for «courier in Tver», not «retail vacancies». The project covers those queries automatically — from a directory of salaries, geo and coordinates, Nuxt pre-generates around 230 separate landing pages for each «vacancy × city» pair, filling each one with the current salary. An applicant finds their city's page, sees the number and applies through a form that goes straight into the employer's CRM. Built for SberMarket, Samokat and Magnit — couriers, pickers and drivers.

  • Captures low-frequency queries like «courier in Tver»: around 230 pages via routes /[vacancy]/[city], each with its own meta tags and headings declined by grammatical case (useSeoMeta, lvovich)
  • Salaries on the pages are always current: a custom Node.js ETL pulls data from CSV and JSON, matches it against a directory of 1,102 Russian cities (cases, coordinates, population) and recomputes the figures by formula
  • Applicants find their city on a map: OpenLayers with custom SVG markers for active cities, tooltips and click-through to the city's page
  • Applications don't get lost: Cyrillic name validation and phone normalization (VeeValidate + Yup), submission straight into the employer's CRM and conversion tracking in Yandex.Metrica
  • Three brands on one codebase: shared UI components plus isolated sets for SberMarket, Samokat and Magnit; static builds ship atomically via scp/ssh
  • The approach works: over two years these pages drew 986,000 visitors, and employers accepted 32,848 applications
Nuxt 3SSGNode.jsOpenLayersVeeValidateTailwind CSSlvovich
Brickick

Brickick

Brickick is an interactive in-browser 3D LEGO configurator built on TresJS: it loads an LDraw model, orbits it freely, recolors the body and swaps wheels with a live 3D preview, plays a step-by-step build animation and opens moving parts — doors, hood, tailgate. All graphics run on the GPU via Three.js, with no server: heavy part parsing is moved to offline pre-baking, and the scene renders on demand.

  • A heavy model opens in a fraction of a second: pre-baking into gzip-GLB shrinks the build from 16.5 MB to 2 MB and loads it in roughly 0.3 seconds
  • Won't cook your laptop or phone: the scene only redraws when something changes (on-demand rendering), and geometry merging cuts thousands of draw calls down to dozens even on ~1500-part models — at rest GPU load drops to near zero
  • Recoloring and part swaps in real time: two body zones and interchangeable wheels, with a 3D preview of each variant generated automatically
  • Step-by-step assembly like a paper manual: a slider and a player with autoplay; 354 steps implemented via setDrawRange, so switching a step rebuilds nothing
  • Opening doors, hood and tailgate — declaratively, by rotating around a hinge through pivot wrappers and a smooth rAF tween; the UI adapts to desktop and mobile
Vue 3TresJSThree.jsPiniaVite
DXF-kit

DXF-kit

dxf-kit opens AutoCAD DXF drawings right in the browser: an engineer doesn't need to install a heavy CAD package, and the file goes nowhere — it stays on their machine. At its core is a framework-agnostic rendering engine with ready-made wrappers for Vue 3, React and Web Components, so the viewer drops into almost any stack.

  • Opens real-world drawings, not just clean examples: 22 DXF entity types, 29 AutoCAD hatch patterns and linetypes with LTSCALE support. The parser is written from scratch, with no external dependencies
  • Text stays crisp at any zoom level — it's vector, not raster
  • You can measure a drawing, not just look at it: distance, area, angle. Plus a layer panel, dark theme and accessibility (ARIA)
  • Drops into any stack: five npm packages — the engine core and ready-made wrappers for Vue 3, React and Web Components
  • People actually use it: around 8,000 npm downloads over the past year (as of July 2026). The engine is covered by 1,504 automated tests — 36% of the codebase
TypeScriptThree.jsWebGL 2Vue 3ReactWeb ComponentsVite
Crux

Crux

Crux turns a bouldering board into a route builder: a climber “paints” the holds, assigning roles — start, hands, feet, top — sets the grade and shares the finished route as a plain link. There is no server at all: the whole route is encoded into the link itself, and saved routes live in the browser. So it works both online and offline, installs like a regular app and builds for Android as an apk.

  • Routes are drawn with a finger, right there in the gym: tap and swipe paint the holds on the board's SVG grid, assigning roles — start, hand, foot, top
  • Share a route with anyone, no sign-up needed: it's encoded entirely into the link (?r=…), with nothing uploaded to a server
  • Your routes are always at hand, even when the gym has no signal — they're stored right in the browser (IndexedDB)
  • Speaks the grading systems climbers actually use: Font, V-scale, French and color labels
  • Installs as an app and works without a network (a PWA on Workbox); builds for Android via Capacitor when needed; interface in Russian and English
Vue 3QuasarTypeScriptPiniaIndexedDBWorkboxCapacitor
Aleph

Aleph

Aleph merges best-books lists from experts around the world into a single canon map: you see what the whole world recognises and what only a single list does. Not a “top books” chart, but a mirror of how different eras and countries argue about what matters. The database currently holds 662 books and 541 authors from seven source lists.

  • A canon map you can pan and zoom: D3 computes the layout (scale, force, beeswarm), Vue renders it, and pan/zoom is hand-written on PointerEvent
  • Opens instantly: every book, author and list is its own pre-rendered page (SSG with Astro 5), with interactivity confined to Vue 3 islands
  • Transparent methodology: data sits as flat JSON right in git — file-per-book plus pre-computed indexes. No database, no runtime requests, and every figure can be checked against commit history
  • Data is gathered by a Python ETL: four idempotent stages (MediaWiki, Wikidata → covers → indexes) with request caching — a rebuild never breaks what's already there
  • UI on Open Props and scoped CSS, headless Reka UI components as needed; static hosting on GitHub Pages
Astro 5Vue 3D3Reka UIOpen PropsPython
Time Spent · Trello Power-Up

Time Spent · Trello Power-Up

Time Spent embeds into Trello cards and turns a board into a time tracker: log hours right on a card, while the dashboard rolls them up into weekly stats, reports and exports. The team doesn't need a separate tracker or yet another account — everything lives inside Trello itself, with no external servers and no tracking.

  • Time is logged where the work is: a form right on the card, editing in place and a total-time badge on the cover
  • You can see where the week went: a dashboard with a per-day chart (Chart.js) and a task table grouped by lists
  • Works for a team: entries are tied to their author, with a «mine / total» split and a «show only mine» filter
  • Enter time however you like: decimal (1.5), hours:minutes (2:15) or plain text (2h15m)
  • Period reports export to HTML and Excel (XLSX). Privacy-first: data stays inside Trello and never reaches third-party servers
  • Published on the Trello marketplace: 500 installs in six months (as of July 2026)
JavaScriptTrello Power-Up SDKChart.jsSheetJSVitestNetlify
commit-date-changer

commit-date-changer

An interactive CLI tool for safely changing git commit dates. It works in two modes — an interactive one with step-by-step prompts and a command-line one for automation. By default it only touches unpushed commits, keeping repository history safe.

  • Won't let you wreck your history: by default it edits only unpushed commits, with warnings and guards for pushed ones
  • Two modes: interactive, with step-by-step prompts and colored output — and command-line (CLI), for scripts
  • Validates chronological order on its own and can process several commits in one batch
  • ISO 8601 dates and JSON output — easy to call from automation
  • Published on npm: around 500 downloads over the past year (as of July 2026). Interface in Russian and English (i18next)
TypeScriptNode.jsCommanderInquireri18next
arbaev.com

arbaev.com

The personal portfolio site you're reading right now: web projects, street photography and notes on books under one roof. Built on Nuxt 4 with static generation — only ready-made static files ship to hosting, with no server or database. It doubles as a portfolio case itself: light typography, a dark theme and two language versions.

Lighthouse scores

  • 100
    Performance
  • 100
    Accessibility
  • 100
    Best Practices
  • 100
    SEO

Lighthouse 13.4.1 · Desktop · measured 27.07.2026

  • Loads instantly and runs on plain shared hosting: nuxi generate compiles the whole site to static files — no backend, no database and no monthly server bill
  • Content is edited like plain text: blog posts, photo series and books live as Markdown files right in the repo, and zod schemas won't let a post ship with broken fields (@nuxt/content)
  • Two locales with @nuxtjs/i18n: Russian on /, English on /en/ — with a language switch and correct SEO meta for each
  • Reads the same on a phone and on a monitor, in light and dark theme — responsive layout and dark mode on Nuxt UI v4
  • Over 1,300 photographs migrated from the old WordPress with their original URLs preserved — images served through @nuxt/image in avif/webp
  • Analytics without a single cookie or consent banner: the tracker weighs 9 KB against the 107 KB of the previous Yandex.Metrica and collects no personal data
  • Accessibility verified rather than claimed: text contrast brought up to WCAG AA, and links in body text are distinguishable by more than colour alone
Nuxt 4Vue 3Nuxt UI v4Tailwind CSS v4@nuxt/content@nuxt/imagei18nTresJSSSG