<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Erik Novikov</title>
    <description>The latest articles on DEV Community by Erik Novikov (@eriknovikov).</description>
    <link>https://dev.to/eriknovikov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2553696%2Ff55ce885-4244-4cbf-9f48-53ff49d760a7.jpg</url>
      <title>DEV Community: Erik Novikov</title>
      <link>https://dev.to/eriknovikov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eriknovikov"/>
    <language>en</language>
    <item>
      <title>The tech market is tough. Here's what actually matters.</title>
      <dc:creator>Erik Novikov</dc:creator>
      <pubDate>Tue, 07 Apr 2026 19:35:39 +0000</pubDate>
      <link>https://dev.to/eriknovikov/the-tech-market-is-tough-heres-what-actually-matters-4ekb</link>
      <guid>https://dev.to/eriknovikov/the-tech-market-is-tough-heres-what-actually-matters-4ekb</guid>
      <description>&lt;h2&gt;
  
  
  The situation
&lt;/h2&gt;

&lt;p&gt;Layoffs, an influx of new devs, and AI getting more capable every month. The market is genuinely harder than it was a few years ago — both at entry level and senior. Supply is up, so the average developer's value is down. That's just supply and demand.&lt;/p&gt;

&lt;p&gt;But the average developer is not you. Here's why it's not as grim as it looks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Competence still wins
&lt;/h2&gt;

&lt;p&gt;The market isn't homogeneous. Two developers with the same title and years of experience can be worlds apart in actual ability. What separates them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Problem-solving over knowledge accumulation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The developer who knows three frameworks but can't think through an unfamiliar problem is less valuable than the one with strong fundamentals who can adapt fast. Protocols, concurrency, system design, debugging, fixing and shipping under pressure — these transfer across stacks. Knowing by heart a specific library or framework doesn't.&lt;/p&gt;

&lt;p&gt;A concrete example: migrating a microservice from Java to Go. A developer who's never touched Java might freeze. A developer with solid fundamentals in how languages handle concurrency and how services communicate will figure it out. Be the second developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI leverage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use AI to plan, brainstorm, review, and code — but stay in the driver's seat. Vibe-coding your way to a shipped feature might look fast until you spend hours debugging a system you never actually understood. AI is a force multiplier, not a replacement for understanding what you're building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Learning rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In tech, what you know today matters less than how fast you can learn something new and apply it. The half-life of any specific skill is shrinking. Your ability to pick things up quickly is the most durable asset you have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final word
&lt;/h2&gt;

&lt;p&gt;Don't stress over the market. Get extremely good instead. Strong fundamentals, smart use of AI, and a fast learning rate will put you ahead of most. Focus on those and the rest takes care of itself.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I built voice-type</title>
      <dc:creator>Erik Novikov</dc:creator>
      <pubDate>Tue, 07 Apr 2026 19:17:00 +0000</pubDate>
      <link>https://dev.to/eriknovikov/how-i-built-voice-type-3i2p</link>
      <guid>https://dev.to/eriknovikov/how-i-built-voice-type-3i2p</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;This post breaks down &lt;a href="https://github.com/eriknovikov/voice-type" rel="noopener noreferrer"&gt;Voice Type&lt;/a&gt; — a system-wide speech-to-text tool for Linux I built and use daily. I'll cover why I built it, how it works under the hood, and what I learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Two reasons: wrist pain and productivity.&lt;/p&gt;

&lt;p&gt;Modern dev workflows involve a ton of prompting — LLMs, search, documentation. If you're doing that all day with a keyboard, your wrists notice. And beyond the ergonomics, you simply speak faster than you type. Offloading even part of that to voice has a real impact.&lt;/p&gt;

&lt;p&gt;The obvious solution was a local STT model. I tried SpeechNote on Linux with a Whisper.cpp small model — it wasn't accurate enough and had noticeable latency. Running a larger model wasn't an option either: I'm on an 8GB RAM laptop, and my dev setup (VSCode, Chrome, Docker, DBeaver, etc.) already pushes that. A 3–4GB model sitting in RAM wasn't viable.&lt;/p&gt;

&lt;p&gt;I eventually found that Chrome's built-in Web Speech API — which routes audio to Google's servers under the hood — matches the accuracy and speed of much larger models like Whisper large, with virtually zero local resource usage. That was the unlock.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Voice Type launches a headless Chrome instance via Puppeteer and uses the Web Speech API to do real-time transcription. Here's the flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Browser&lt;/strong&gt; — Chrome runs the Web Speech API with &lt;code&gt;interimResults: true&lt;/code&gt;, which streams partial transcripts as you speak in real time. These flow in via Google's WebSocket infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IPC&lt;/strong&gt; — When a new interim result arrives in the browser, it triggers a callback into the main Node.js daemon. This is done via Puppeteer's &lt;code&gt;exposeFunction&lt;/code&gt;, which leverages the Chrome DevTools Protocol WebSocket connection to invoke a function in the main process in real time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Diffing&lt;/strong&gt; — The daemon keeps track of &lt;code&gt;currentText&lt;/code&gt;. On every update, it runs a diff: if nothing changed, do nothing. If it changed, find the longest common prefix between the old and new text, send the right number of backspaces, and type the new characters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Typing&lt;/strong&gt; — Text is typed system-wide via &lt;code&gt;dotool&lt;/code&gt;. Standard ASCII goes through directly. Accented characters, emojis, and CJK are handled via GNOME's Unicode Hex Input sequence (&lt;code&gt;Ctrl+Shift+U&lt;/code&gt; → hex code → Enter), which makes it work across languages without needing to match the user's keyboard layout.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is why Voice Type can correct itself mid-sentence without retyping everything from scratch — it only fixes what changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy note
&lt;/h2&gt;

&lt;p&gt;Since the Web Speech API is powered by Google's servers, your audio does leave your machine. Worth knowing before you use it for anything sensitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I actually use it
&lt;/h2&gt;

&lt;p&gt;Mostly for prompting and writing blog posts like this one. Once it's bound to a key, it gets out of the way completely — press, speak, done. It supports text and sound notifications, though I prefer them disabled — GNOME already shows a mic icon in the system tray when the mic is active.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;STT is underrated as a dev tool. If you're on Linux, give &lt;a href="https://github.com/eriknovikov/voice-type" rel="noopener noreferrer"&gt;Voice Type&lt;/a&gt; a try — it's free, open source, and uses almost no resources. If it's useful to you, a star on GitHub goes a long way. Happy coding!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>stt</category>
      <category>dictation</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How I built dotapro.org</title>
      <dc:creator>Erik Novikov</dc:creator>
      <pubDate>Wed, 01 Apr 2026 15:13:59 +0000</pubDate>
      <link>https://dev.to/eriknovikov/how-i-built-dotaproorg-1jba</link>
      <guid>https://dev.to/eriknovikov/how-i-built-dotaproorg-1jba</guid>
      <description>&lt;h1&gt;
  
  
  How I built dotapro.org
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;This post breaks down &lt;a href="https://dotapro.org" rel="noopener noreferrer"&gt;dotapro.org&lt;/a&gt; — an open-source Dota 2 analytics platform for professional matches. I'll cover why I built it and the technical decisions behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Dota 2 is one of the few games I actually enjoy. I couldn't find a good tool for browsing professional match data with proper filtering, so I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Advanced filtering by league, team, player, and hero&lt;/li&gt;
&lt;li&gt;Real-time ETL pipeline keeping match data up to date&lt;/li&gt;
&lt;li&gt;Fast &lt;code&gt;pg_trgm&lt;/code&gt; similarity search for names&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The React frontend talks to an API Lambda. A separate scraper Lambda runs on a schedule, pulls data from the &lt;a href="https://opendota.com" rel="noopener noreferrer"&gt;OpenDota API&lt;/a&gt;, and inserts it into PostgreSQL on RDS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faydjrmz51x0jq50g80p3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faydjrmz51x0jq50g80p3.png" alt="Architecture" width="666" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage
&lt;/h3&gt;

&lt;p&gt;PostgreSQL on AWS RDS. I briefly ran Postgres manually on an EC2 instance just to understand what managed services actually abstract away — OS patching, backups, vertical scaling. The time cost isn't worth the savings unless you're optimizing hard on infrastructure spend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compute
&lt;/h3&gt;

&lt;p&gt;Two Lambdas: one scraper on an EventBridge schedule, one monolithic API Lambda handling all routes via &lt;code&gt;go-chi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The monolith was a deliberate choice. One codebase, one deployment, and warm starts benefit all endpoints regardless of which one was hit first. I initially over-engineered it — scraper → SQS → ingestor Lambda — then collapsed it into a single Lambda when I realized nothing actually required that complexity.&lt;/p&gt;

&lt;p&gt;Split a Lambda monolith when you have separate teams needing independent deployments, or a specific hot path that needs provisioned concurrency. Otherwise, keep it simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;React + TypeScript + Tailwind + Vite + TanStack Router/Query, deployed to S3 behind CloudFront. Standard setup, nothing unusual.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD
&lt;/h3&gt;

&lt;p&gt;GitHub Actions on push to &lt;code&gt;main&lt;/code&gt;, with OIDC auth to AWS. Selectively redeploys only what changed — UI gets built and synced to S3 with a CloudFront invalidation, Lambdas get compiled and pushed via &lt;code&gt;update-function-code&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Feel free to check it out at &lt;a href="https://dotapro.org" rel="noopener noreferrer"&gt;dotapro.org&lt;/a&gt;. The code is also on &lt;a href="https://github.com/eriknovikov/dotapro" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; — drop a star if you find it useful. Happy coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Welcome to my blog</title>
      <dc:creator>Erik Novikov</dc:creator>
      <pubDate>Thu, 08 Jan 2026 13:56:36 +0000</pubDate>
      <link>https://dev.to/eriknovikov/welcome-to-my-blog-39nk</link>
      <guid>https://dev.to/eriknovikov/welcome-to-my-blog-39nk</guid>
      <description>&lt;h2&gt;
  
  
  What is this blog about?
&lt;/h2&gt;

&lt;p&gt;Throughout this blog I intend to write about tech - full-stack web dev, programming, career advice, Linux, cloud computing, AI, and software development in general. Occasionally I may write about other topics I find interesting, only if I'm absolutely sure it would be of help to you somehow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bit about me
&lt;/h2&gt;

&lt;p&gt;Hey there! I'm Erik, a software dev. I started programming at 17, went to university (Software Engineering), and after that I have been professionally in the industry for a while. It's been an exciting ride, where I've had to learn A LOT, and will continue to do so. IMO, that's the best thing about tech - it evolves all the time. Other than doing "normal dev stuff", I'm currently sharpening my cloud computing (mostly AWS), 3D development, and AI skills. In my free time, you will find me building something cool like &lt;a href="https://github.com/eriknovikov/dotapro" rel="noopener noreferrer"&gt;dotapro.org&lt;/a&gt; (an open-source Dota 2 analytics platform), or &lt;a href="https://github.com/eriknovikov/voice-type" rel="noopener noreferrer"&gt;voice-type&lt;/a&gt; (a free Linux dictation tool with unmatched speed and accuracy).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this blog?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;You'll definitely find something helpful here.&lt;/li&gt;
&lt;li&gt;I genuinely enjoy writing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  About my writing style
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I don't like fluff.&lt;/li&gt;
&lt;li&gt;I keep it casual, concise, and to the point.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I intend to be as value-driven as possible, so I'll only blog about something if I really believe it can be helpful to you. So no, GPT-stenchy blogs with a lot of bs and zero real world utility is something I won't ever do.&lt;/p&gt;

&lt;h2&gt;
  
  
  My socials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/eriknovikov" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linkedin.com/in/eriknovikov" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://t.me/erik_nkv" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>career</category>
    </item>
  </channel>
</rss>
