<?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: Viktor Vítovec</title>
    <description>The latest articles on DEV Community by Viktor Vítovec (@vvitovec).</description>
    <link>https://dev.to/vvitovec</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4011130%2Fda83bf1c-6ad3-4adc-a172-d0d9370b1f83.jpeg</url>
      <title>DEV Community: Viktor Vítovec</title>
      <link>https://dev.to/vvitovec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vvitovec"/>
    <language>en</language>
    <item>
      <title>Codex Needed Better Subagent Control. So I Built It.</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 15 Jul 2026 07:02:18 +0000</pubDate>
      <link>https://dev.to/vvitovec/codex-subagents-are-almost-great-so-i-finished-the-orchestration-layer-myself-1lkk</link>
      <guid>https://dev.to/vvitovec/codex-subagents-are-almost-great-so-i-finished-the-orchestration-layer-myself-1lkk</guid>
      <description>&lt;p&gt;I use Codex every day, and subagents are one of those features where the potential is immediately obvious. They can already work in parallel, use custom roles, and load their own configuration. But once I wanted precise control over model choice, reasoning effort, and a larger queue of jobs, I started hitting differences between the various Codex surfaces.&lt;/p&gt;

&lt;p&gt;So I built my own orchestration layer. Not as a replacement for Codex, but as a more programmatic layer on top of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Codex can already do
&lt;/h2&gt;

&lt;p&gt;Native Codex subagents are not a toy. The current &lt;a href="https://developers.openai.com/codex/subagents" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; describes the built-in &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;worker&lt;/code&gt;, and &lt;code&gt;explorer&lt;/code&gt; roles, custom agents in &lt;code&gt;.codex/agents/*.toml&lt;/code&gt;, thread limits, and per-agent settings for the model, &lt;code&gt;model_reasoning_effort&lt;/code&gt;, sandbox, MCP servers, and skills.&lt;/p&gt;

&lt;p&gt;Codex can spawn a child, wait for it, send follow-up instructions, interrupt it, and bring its result back to the lead agent. For large repetitive workloads, there is also an experimental &lt;code&gt;spawn_agents_on_csv&lt;/code&gt; flow that creates a worker per row and collects structured results into another CSV.&lt;/p&gt;

&lt;p&gt;That is a strong base. The problem is not that Codex lacks subagents. The problem is that capabilities still vary between the desktop app, CLI, tool-backed sessions, and experimental modes. Something that can be expressed in a custom-agent TOML is not necessarily exposed with the same reliability as a dynamic choice on every spawn surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  V1 and V2 subagents in Codex
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;V1&lt;/code&gt; and &lt;code&gt;V2&lt;/code&gt; are not two variants documented as such in the user-facing docs. They are names for two implementations in the &lt;code&gt;openai/codex&lt;/code&gt; upstream.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V1 is the stable path today.&lt;/strong&gt; A lead agent starts child threads, waits for results, and can steer them afterward. Current upstream V1 can pass &lt;code&gt;model&lt;/code&gt; and &lt;code&gt;reasoning_effort&lt;/code&gt; directly at spawn time, while custom-agent TOML can pin them. My particular tool-backed desktop session did not expose those fields in its &lt;code&gt;spawn_agent&lt;/code&gt; schema; it only offered the task name, prompt, and context-fork mode. The limitation is therefore not universal to Codex core, but an inconsistency between surfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V2 is a more ambitious orchestration rebuild.&lt;/strong&gt; It is built around canonical task paths, direct &lt;code&gt;send_message&lt;/code&gt;, &lt;code&gt;followup_task&lt;/code&gt;, and &lt;code&gt;list_agents&lt;/code&gt; tools, and more granular &lt;code&gt;fork_turns&lt;/code&gt; control (&lt;code&gt;none&lt;/code&gt;, &lt;code&gt;all&lt;/code&gt;, or the last N turns). It remains behind a feature flag and is marked &lt;code&gt;UnderDevelopment&lt;/code&gt; upstream. A full-history fork intentionally rejects a different &lt;code&gt;agent_type&lt;/code&gt;, &lt;code&gt;model&lt;/code&gt;, or &lt;code&gt;reasoning_effort&lt;/code&gt;; a child with a different role, model, or effort therefore needs a clean or partial fork. OpenAI collaborators have additionally said in &lt;a href="https://github.com/openai/codex/issues/26753" rel="noopener noreferrer"&gt;GitHub issue discussions&lt;/a&gt; — not in the official docs — that V2 is not yet recommended for stable use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neither version is a good interface for precisely controlled orchestration yet.&lt;/strong&gt; Not because they cannot split up work, but because I do not get reliable control over the model, reasoning effort, and token budget of every child across all Codex surfaces. Upstream supports some of those choices, but product workflows can still lock them, hide them, or take over the decision for me.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ultra&lt;/code&gt; is an even more interesting case. &lt;a href="https://openai.com/index/gpt-5-6/" rel="noopener noreferrer"&gt;OpenAI describes it&lt;/a&gt; as a multi-agent mode that coordinates four agents in parallel by default. It can therefore burn through tokens like almost nothing else, especially once a task starts branching. I would not claim that it is literally the public Codex &lt;code&gt;multi_agent_v2&lt;/code&gt; implementation, or that Ultra subagents recursively spawn more Ultra subagents, because OpenAI has not publicly confirmed either point. The practical limitation is the same either way: I can see the result of very powerful orchestration, but I do not get reliable per-child control over model, effort, depth, and budget.&lt;/p&gt;

&lt;p&gt;This area changes quickly. Treat this section as a snapshot from July 13, 2026, not a permanent verdict on Codex.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I was missing
&lt;/h2&gt;

&lt;p&gt;I wanted the strongest model to act as a control plane: understand the project, split the work, choose the right worker, and verify the integrated result. I did not want every mechanical scan or routine check to inherit the most expensive model at an extreme reasoning setting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The main point is to use the smartest model as the orchestrator and weaker, faster, cheaper models as workers.&lt;/strong&gt; The orchestrator should spend its intelligence on architecture, delegation, and verification; workers should execute tightly scoped jobs at a sensible cost. Without my layer, I cannot reliably assemble and control that hierarchy dynamically across the different Codex surfaces today.&lt;/p&gt;

&lt;p&gt;More specifically, I wanted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;select the model and effort per job instead of hoping the runtime picked what I meant;&lt;/li&gt;
&lt;li&gt;keep feeding a queue programmatically instead of manually spawning dozens of agents;&lt;/li&gt;
&lt;li&gt;allow one writer by default unless ownership scopes were genuinely separate;&lt;/li&gt;
&lt;li&gt;resume after interruption without repeating completed jobs;&lt;/li&gt;
&lt;li&gt;keep a manifest, logs, a hash of the final artifact, and discovered thread IDs when the event stream exposes them;&lt;/li&gt;
&lt;li&gt;run the same workflow on my MacBook, Mac mini, and Linux server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My solution: Codex as the engine, my runner as the control layer
&lt;/h2&gt;

&lt;p&gt;The result is the open-source &lt;a href="https://github.com/vvitovec/codex-orchestration" rel="noopener noreferrer"&gt;vvitovec/codex-orchestration&lt;/a&gt; project. It contains five cooperating skills for decomposition, routing, compact delegation prompts, review, and scaling. I then added a real programmatic runner on top of &lt;code&gt;codex exec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each job is a normal JSONL record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"api-review"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"gpt-5.6-terra"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"effort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"medium"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"sandbox"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"read-only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"workdir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Review the API surface and return concrete risks."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The runner passes the model and effort explicitly to the Codex CLI, limits total and write concurrency, locks a run against duplicate execution, persists an atomic manifest, and verifies that a supposedly successful job actually produced a completed result. It records the output size and SHA-256 hash, so a missing or modified artifact cannot hide behind an old &lt;code&gt;succeeded&lt;/code&gt; state during resume.&lt;/p&gt;

&lt;p&gt;A timed-out writer is not automatically repeated unless the job is explicitly marked safe and idempotent. Parallel writers require an explicit opt-in and unique &lt;code&gt;ownership_scope&lt;/code&gt; values. These details are boring, but they are what separates a nice orchestration demo from a workflow I am willing to point at a real repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is different, and where native Codex is still better
&lt;/h2&gt;

&lt;p&gt;My layer gives me more &lt;strong&gt;programmatic freedom&lt;/strong&gt;. The requested model, effort, sandbox, timeout, retry policy, and ownership are not merely prompt suggestions: the runner passes them as CLI arguments or configuration and records them in a persistent manifest. That guarantees the exact launch request, not the effective backend route, which current &lt;code&gt;codex exec --json&lt;/code&gt; does not explicitly attest. The queue can contain three jobs or three hundred and still behaves like a queue rather than a long chain of manual tool calls.&lt;/p&gt;

&lt;p&gt;I am not pretending that I built a better Codex. Native subagents have a huge integration advantage: their threads are visible in the UI, I can steer them naturally, and the lead agent can collaborate with them conversationally. My runner is stronger for deterministic batches and auditable automation. The native system is nicer for interactive work.&lt;/p&gt;

&lt;p&gt;Codex App Server already exposes better route information and reroute events, so that is the natural next backend for this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  One of the few unfinished parts. For now.
&lt;/h2&gt;

&lt;p&gt;This is not an attack on Codex. Quite the opposite: it is my main working tool because the team ships at an absurd pace and clearly cares about the product. &lt;a href="https://x.com/thsottiaux" rel="noopener noreferrer"&gt;Thibault “Tibo” Sottiaux&lt;/a&gt;, one of the people behind Codex, is unusually open on X and GitHub, responds to concrete problems, and the team often addresses user feedback before another company would finish scheduling the roadmap meeting.&lt;/p&gt;

&lt;p&gt;I have also been testing &lt;a href="https://openai.com/index/gpt-5-6/" rel="noopener noreferrer"&gt;GPT-5.6 Sol and the other models&lt;/a&gt; pretty intensely since release, and I think they are excellent. I have produced more code and finished more work with them than ever before. They can also keep going for absurdly long runs: the cover screenshot is one of my own GPT-5.6 Sol Ultra runs, at 23 hours and 50 minutes.&lt;/p&gt;

&lt;p&gt;That is why I expect OpenAI to improve the native multi-agent workflow quickly. Custom agents and CSV fan-out already point in the right direction. My orchestration gives me the control I need today, while also being a useful experiment in how agent routing could become more precise.&lt;/p&gt;

&lt;p&gt;Subagents are one of the few parts of Codex that still feel genuinely unfinished to me. &lt;strong&gt;FOR NOW.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I keep the rest of my technical experiments and builds in my &lt;a href="https://www.vvitovec.com/en/projects" rel="noopener noreferrer"&gt;projects&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codex</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your Mac is protecting you! (but is it worth it?)</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Mon, 06 Jul 2026 09:59:21 +0000</pubDate>
      <link>https://dev.to/vvitovec/your-mac-is-protecting-you-but-is-it-worth-it-1g34</link>
      <guid>https://dev.to/vvitovec/your-mac-is-protecting-you-but-is-it-worth-it-1g34</guid>
      <description>&lt;p&gt;Your Mac is trying to keep you safe. That is good. But when I run Codex all day, with parallel agents, computer use, browser work and a lot of local process launches, the next question becomes interesting too: &lt;strong&gt;how much performance does that safety cost?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I made a small benchmark: &lt;a href="https://github.com/vvitovec/macos-gatekeeper-codex-benchmark" rel="noopener noreferrer"&gt;macos-gatekeeper-codex-benchmark&lt;/a&gt;. It is not a formal paper. It is a practical test from my real workflow on a MacBook Air.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I was actually testing
&lt;/h2&gt;

&lt;p&gt;On macOS, part of this protection comes from &lt;a href="https://support.apple.com/guide/security/gatekeeper-and-runtime-protection-sec5599b66df/web" rel="noopener noreferrer"&gt;Gatekeeper&lt;/a&gt; and the &lt;a href="https://www.manpagez.com/man/8/syspolicyd/" rel="noopener noreferrer"&gt;&lt;code&gt;syspolicyd&lt;/code&gt;&lt;/a&gt; process. Apple describes Gatekeeper as a technology that helps make sure only trusted software runs on a Mac. For normal use, that is mostly invisible. You download an app, macOS checks it, and you open it. If you want the deeper rabbit hole, Scott Knight's &lt;a href="https://knight.sc/reverse%20engineering/2019/02/20/syspolicyd-internals.html" rel="noopener noreferrer"&gt;&lt;code&gt;syspolicyd&lt;/code&gt; internals&lt;/a&gt; write-up is a good technical read.&lt;/p&gt;

&lt;p&gt;My workflow is different. Codex can run multiple jobs at once, use browser/computer control, execute terminal commands, hand work to other agents and create a lot of small local process launches. That is exactly where tiny system checks can become very visible.&lt;/p&gt;

&lt;p&gt;I did not want to disable Gatekeeper globally. That might be fast, but it is a bad default. I wanted to know whether the issue was quarantine metadata, first-run assessment of many executable paths, or something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benchmark setup
&lt;/h2&gt;

&lt;p&gt;The repo includes the scripts and the results. The main benchmark ran &lt;code&gt;codex help&lt;/code&gt; repeatedly under a few conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;RUN_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;baseline &lt;span class="nv"&gt;TOTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;20 &lt;span class="nv"&gt;CONCURRENCY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="nv"&gt;REPS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="nv"&gt;CMD_TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8 scripts/run-codex-gatekeeper-benchmark.zsh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second benchmark was smaller and cleaner. It used a tiny locally compiled Mach-O executable and compared one clean path, one quarantined path, many clean copies and many quarantined copies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;TOTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100 &lt;span class="nv"&gt;CONCURRENCY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10 &lt;span class="nv"&gt;REPS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="nv"&gt;CMD_TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="nv"&gt;MANY_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;50 scripts/run-case-study-extras.zsh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also tested temporary &lt;code&gt;syspolicyd&lt;/code&gt; priority changes and a daemon restart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;renice +10 &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;syspolicyd-pid&amp;gt;
renice +19 &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;syspolicyd-pid&amp;gt;
killall syspolicyd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are not commands I would recommend as a normal fix. They were there to check whether they were real mitigations. They were not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the numbers said
&lt;/h2&gt;

&lt;p&gt;The easiest way to read the benchmark is not through the internal test names. It is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The normal, trusted Codex install was fast.&lt;/strong&gt; Repeatedly launching the real Codex binary that macOS had already seen stayed basically instant for my workflow. In the small burst test, 20 launches finished in a fraction of a second.&lt;/p&gt;

&lt;p&gt;The slow part was different: creating a lot of new executable paths and asking macOS to run them right away. When I copied the Codex binary into many fresh locations and launched those copies in parallel, the first run jumped &lt;strong&gt;from “blink and it is done” to roughly 11 seconds&lt;/strong&gt;. That is the part you feel as the machine suddenly dragging.&lt;/p&gt;

&lt;p&gt;The tiny executable test made the same point in a cleaner way: a tiny trusted helper could be launched 100 times almost instantly, while the same kind of helper with quarantine attached did not really get through the run before the timeout. New clean files were better than quarantined files, but the first run could still be noticeably slower until macOS assessed them once. I also tried the tempting system-level fixes, like lowering &lt;code&gt;syspolicyd&lt;/code&gt; priority and restarting it, but they did not solve the real problem. The better fix is more boring: keep trusted tools clean, avoid unnecessary executable path churn, and warm up new generated tools before throwing a lot of parallel agents at them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am not taking from this
&lt;/h2&gt;

&lt;p&gt;I am not taking the lesson as "disable Gatekeeper". Actually the opposite. I did not run &lt;code&gt;spctl --master-disable&lt;/code&gt;, and I do not want this to become a generic performance trick.&lt;/p&gt;

&lt;p&gt;The better rule is narrower:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xattr &lt;span class="nt"&gt;-p&lt;/span&gt; com.apple.quarantine /path/to/trusted/tool
xattr &lt;span class="nt"&gt;-d&lt;/span&gt; com.apple.quarantine /path/to/trusted/tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That only makes sense for tools I actually trust and understand. Not random downloads. Not a global cleanup.&lt;/p&gt;

&lt;p&gt;The other practical rule is about path churn. If a workflow creates many executable files, do not immediately spawn all of them at high concurrency. The first run may be slower because macOS is assessing new paths. Warming them at lower concurrency can be better than letting a large agent run make the system feel stuck.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I will probably do
&lt;/h2&gt;

&lt;p&gt;I will probably keep everything on. The reason is simple: I can offload a lot of the pressure. If Codex is doing heavier work, I can hand jobs from my workstation MacBook Air to my Mac mini or to my &lt;a href="https://www.vvitovec.com/en/blog/old-gaming-pc-linux-server" rel="noopener noreferrer"&gt;Linux server&lt;/a&gt;. That is a better tradeoff for me than weakening security on my main laptop.&lt;/p&gt;

&lt;p&gt;But for performance maxers, this is an interesting thing to look into. Not because they should turn off protection, but because they can find the specific places where macOS keeps checking things that are already trusted inside their own workflow.&lt;/p&gt;

&lt;p&gt;The full benchmark, scripts and raw results are here: &lt;a href="https://github.com/vvitovec/macos-gatekeeper-codex-benchmark" rel="noopener noreferrer"&gt;github.com/vvitovec/macos-gatekeeper-codex-benchmark&lt;/a&gt;. You can also see more of my practical build work on my &lt;a href="https://www.vvitovec.com/en/projects" rel="noopener noreferrer"&gt;projects page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you work with coding agents, automation or custom build tools on a Mac, it is worth checking whether your bottleneck is really just CPU. Sometimes it is the security layer doing exactly what it is supposed to do. Just very often.&lt;/p&gt;

</description>
      <category>macos</category>
      <category>codex</category>
      <category>performance</category>
      <category>automation</category>
    </item>
    <item>
      <title>Why (not)learn programming.</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:57:28 +0000</pubDate>
      <link>https://dev.to/vvitovec/why-notlearn-programming-f93</link>
      <guid>https://dev.to/vvitovec/why-notlearn-programming-f93</guid>
      <description>&lt;p&gt;A few years ago, programming felt like the default answer to: &lt;em&gt;what should I learn if I want a valuable skill?&lt;/em&gt; And honestly, it made sense. If you knew Python, JavaScript, or TypeScript, you could suddenly build things that most people could only describe.&lt;/p&gt;

&lt;p&gt;Today I would not tell someone: learn a programming language and you are set. &lt;strong&gt;Knowing syntax is not the main skill anymore.&lt;/strong&gt; AI can produce a ridiculous amount of code in a day. Roughly the kind of volume a normal employed developer would write by hand over years. The exact number is not the point. The point is that writing lines of code became much cheaper.&lt;/p&gt;

&lt;p&gt;That does not mean programming is useless. It means the reason to learn it changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming work changed
&lt;/h2&gt;

&lt;p&gt;In the past, a big part of the value was simply being able to turn an idea into code. You knew how to write an endpoint, a component, a script, a database query, an API integration. That is still useful, but it is not as rare as it used to be.&lt;/p&gt;

&lt;p&gt;If I have a fairly clear system in my head today, AI can write a large part of the implementation for me. Not perfectly. Not without review. But fast enough that &lt;code&gt;typing code&lt;/code&gt; is usually not the bottleneck anymore.&lt;/p&gt;

&lt;p&gt;The bottleneck is more like: do you know what should be built? Do you know where the boundary should be between frontend, backend, and database? Do you know when a simple script is enough and when you need a real app? Can you tell when AI wrote code that looks clean but will break in a month?&lt;/p&gt;

&lt;p&gt;That is the new line, in my opinion.&lt;/p&gt;

&lt;h2&gt;
  
  
  A language is not enough
&lt;/h2&gt;

&lt;p&gt;Learning Python or TypeScript is great. Really. I just would not expect it to automatically make you employable or make someone trust you with a real product.&lt;/p&gt;

&lt;p&gt;A language is a tool. If you only know the language, you mostly know how to phrase instructions for a computer. But real software is not a language exam. It is decisions around data, users, errors, deployment, security, performance, UI, operations, and a thousand small details that tutorials often skip.&lt;/p&gt;

&lt;p&gt;I know Python and JavaScript/TypeScript, but honestly, I barely write most code by hand anymore. Most of the useful work is deciding how the project should behave, how to split it up, what should stay simple, what needs to be robust, where it can fail, and how to verify it. On projects like my &lt;a href="https://www.vvitovec.com/en/projects/portfolio-web" rel="noopener noreferrer"&gt;portfolio&lt;/a&gt; or internal tools, the main work is often the system, not the lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would learn instead of “just programming”
&lt;/h2&gt;

&lt;p&gt;If I started from zero today, I would still learn coding basics. But I would treat them as the entry ticket, not the final goal.&lt;/p&gt;

&lt;p&gt;I would learn product development first. How to take a messy problem and turn it into something someone actually uses. How to tell whether I am building the right thing. How to choose a small first version instead of a giant plan that never ships.&lt;/p&gt;

&lt;p&gt;Then I would learn how programs are structured. Not necessarily writing every file manually, but understanding why a project has folders, modules, database models, API layers, tests, env vars, and a deployment pipeline. This is exactly where AI still needs a person holding the direction.&lt;/p&gt;

&lt;p&gt;And I would learn problem solving. Reading errors. Finding causes. Figuring out whether the issue is in the database, cache, config, network, UI, or my own assumptions. AI helps a lot here, but it still needs someone who knows what to check next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why programming is still worth learning
&lt;/h2&gt;

&lt;p&gt;I do not want this to sound like “do not learn code.” That would be stupid. If you do not understand code at all, you are completely dependent on whatever AI outputs. That is risky.&lt;/p&gt;

&lt;p&gt;Programming basics let you judge whether AI output makes sense. You can see when a function does something different from what you asked. You understand why types do not match. You can spot a piece of code that bypasses security or a migration that might delete data.&lt;/p&gt;

&lt;p&gt;You also ask better questions. When you use tools like &lt;a href="https://openai.com/codex/" rel="noopener noreferrer"&gt;OpenAI Codex&lt;/a&gt; or other coding agents, the result depends a lot on whether you can describe the problem precisely. “Build me an app” is not enough. You need to know the inputs, outputs, states, and constraints.&lt;/p&gt;

&lt;p&gt;So yes, learn programming. Just do not treat it as the final destination.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new value is orientation
&lt;/h2&gt;

&lt;p&gt;I think the gap will grow between people who can write some code and people who can orient themselves inside software.&lt;/p&gt;

&lt;p&gt;Orientation means you can open an unfamiliar project and slowly understand what is going on. You can find where a bug starts. You can build a mental map of the system. You know what to give AI, what to review manually, and when the better solution is to simplify instead of adding more code.&lt;/p&gt;

&lt;p&gt;That is much stronger than memorizing syntax. AI can fill in syntax. But a bad product or architecture decision can be accelerated by AI too, which only makes it more expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  So: should you learn programming or not?
&lt;/h2&gt;

&lt;p&gt;Yes, learn it. But not with the idea that knowing one language is a career by itself.&lt;/p&gt;

&lt;p&gt;Learn programming so you understand what AI is doing. Learn to build small things from start to finish. Learn to read existing projects. Learn to structure work. Learn product thinking. Learn to verify, not only generate.&lt;/p&gt;

&lt;p&gt;Writing code is cheaper than it used to be. &lt;strong&gt;Knowing what code should exist in the first place is more valuable than it used to be.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the better reason to learn programming now.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>product</category>
    </item>
    <item>
      <title>The barrier to entry into tech does not exist anymore.</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:57:26 +0000</pubDate>
      <link>https://dev.to/vvitovec/the-barrier-to-entry-into-tech-does-not-exist-anymore-3ooj</link>
      <guid>https://dev.to/vvitovec/the-barrier-to-entry-into-tech-does-not-exist-anymore-3ooj</guid>
      <description>&lt;p&gt;Getting into tech is easier now than it has ever been. Not because programming, debugging, or building products suddenly became trivial. More because &lt;strong&gt;access to information is barely the blocker anymore&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before, you had to find a book, a course, a smarter person, or dig through forums until something clicked. Then the internet and YouTube changed the game. Now AI pushes it even further, because you can keep asking questions in one thread until the thing finally makes sense.&lt;/p&gt;

&lt;p&gt;That changes the entry point into tech more than a lot of people admit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curiosity is still the best teacher
&lt;/h2&gt;

&lt;p&gt;I did not get into this through some serious plan like: now I will become a programmer. It started in a much more normal way. I was a gamer and I wanted to mess with things around games.&lt;/p&gt;

&lt;p&gt;For a lot of people, that game is &lt;a href="https://www.minecraft.net/" rel="noopener noreferrer"&gt;Minecraft&lt;/a&gt;. I still think it is one of the best games for pulling someone into technology, because it naturally rewards curiosity. You want to change something, add something, understand why something works the way it does. Suddenly you are not only playing a game anymore. You are dealing with files, servers, plugins, mods, commands, and eventually code.&lt;/p&gt;

&lt;p&gt;That is a very good way in, because it does not feel like forced learning. It is not: here is a syllabus, now suffer. It is more like: I want this thing, I do not know how to do it, so I will try to figure it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The internet already broke most of the barrier
&lt;/h2&gt;

&lt;p&gt;I never really built my learning around paid courses. Not because all paid courses are bad, but because for the way I learn, they were not necessary. There is so much information online that if you have some interest and patience, you can learn almost anything.&lt;/p&gt;

&lt;p&gt;YouTube and the open web taught a lot of people things that school or formal courses never did. Not because school is useless, but because the internet is closer to real problems. Want to run a server, fix a React error, understand a database, write a script, set up domains, or automate emails? Someone already had that problem. Someone recorded a video, wrote an article, or argued about it in a forum.&lt;/p&gt;

&lt;p&gt;That is a huge shift. Access used to be the problem. Now the harder part is choosing what to try first.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI made learning feel like a conversation
&lt;/h2&gt;

&lt;p&gt;In the last two years, this moved again. Before, you searched Google, opened ten tabs, read different answers, and tried to combine them into something that matched your exact problem.&lt;/p&gt;

&lt;p&gt;With AI, it feels more like an ongoing conversation. You ask. You get an explanation. You do not understand it? Ask for a simpler version. Want an example? Ask for one. Do not know what to ask? Ask what you should ask.&lt;/p&gt;

&lt;p&gt;For a beginner, this is extremely strong. They do not immediately need to be good at search keywords, filtering old answers, reading long documentation, or guessing whether a Stack Overflow thread from 2014 is still relevant. They can get a first map of the problem and move step by step.&lt;/p&gt;

&lt;p&gt;And now it is not only about explanations. Tools like &lt;a href="https://openai.com/codex/" rel="noopener noreferrer"&gt;Codex&lt;/a&gt; or &lt;a href="https://claude.com/product/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; can open a project, write code, edit files, set up config, run tests, and get something working. If you want to build almost anything practical - a website, automation, small internal tool, script, data import, or API connection - you often do not need to start from a blank editor anymore. You describe the outcome and an agent can build the first version for you.&lt;/p&gt;

&lt;p&gt;Of course AI can be wrong. You still need to think, test things, and verify the result. But as a starting engine, it is ridiculously convenient. We moved from searching physical libraries, to searching the internet, to asking &lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; or a similar tool and continuing from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is still hard
&lt;/h2&gt;

&lt;p&gt;This does not mean everything is easy. It means the main obstacle changed.&lt;/p&gt;

&lt;p&gt;Information is almost free. Tools are available. AI can suggest a plan, explain an error, write a first version, set up a project, and tell you what to try next. But it still cannot solve the most important part for you: &lt;strong&gt;wanting to do it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Forced learning is much harder than starting from a hobby. When the thing itself interests you, you survive debugging, messy docs, bad tutorials, and the moment where something does not work for two hours because of one stupid mistake. When you only do it because you feel like you should, every blocker feels like the end.&lt;/p&gt;

&lt;p&gt;The second hard part is finding an idea. Some people have a head full of problems they want to solve. Some stare at an empty editor and have nothing. But even that can be worked around. Look at your normal day and ask: what do I do manually, what slows me down, what could be faster, cleaner, or more fun?&lt;/p&gt;

&lt;p&gt;That is usually better than trying to invent a startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  A first project should be tiny
&lt;/h2&gt;

&lt;p&gt;If I had to recommend a first project for this week, it would not be a huge app. It would be something small that solves one annoying problem from your own life.&lt;/p&gt;

&lt;p&gt;If you are a gamer, try a tiny game tweak, config, simple mod, server script, or something around your community. If you have too many emails, try an automation that summarizes them and drafts a reply in your style. If you repeat some task at school, work, or home, try making it faster.&lt;/p&gt;

&lt;p&gt;It does not need to be perfect. The point is being able to say: right now I do this manually, and I want to make it faster, cleaner, or more fun.&lt;/p&gt;

&lt;p&gt;That is how small things naturally turn into real projects. For me it leads into websites, automations, internal tools, and the kind of work I show in my &lt;a href="https://www.vvitovec.com/en/projects" rel="noopener noreferrer"&gt;portfolio projects&lt;/a&gt;. But the principle stays the same: take a problem, build a small first version, break it, fix it, learn the next thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The barrier is low, but the work is still real
&lt;/h2&gt;

&lt;p&gt;The biggest lie about tech now is that you need some special entry pass. You do not. You need curiosity, a bit of stubbornness, and the willingness to build small things before they look elegant.&lt;/p&gt;

&lt;p&gt;AI and the internet will not create motivation for you. But if you already have the motivation, starting today is almost comically accessible.&lt;/p&gt;

&lt;p&gt;That is good news. Not because everyone has to become a programmer. More because the less people are scared of technology, the more small annoying problems they can solve for themselves.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>learning</category>
      <category>tech</category>
      <category>tools</category>
    </item>
    <item>
      <title>I Want to Build Things That Save Work</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:48:47 +0000</pubDate>
      <link>https://dev.to/vvitovec/i-want-to-build-things-that-save-work-2edi</link>
      <guid>https://dev.to/vvitovec/i-want-to-build-things-that-save-work-2edi</guid>
      <description>&lt;p&gt;I have built a lot of websites. I still build them, and honestly, I think I have become pretty good at it. I still enjoy making a page feel fast, clear, polished, and useful.&lt;/p&gt;

&lt;p&gt;But websites by themselves are not really the thing I want to spend my whole future doing.&lt;/p&gt;

&lt;p&gt;I already wrote about this from a slightly different angle in &lt;a href="https://www.vvitovec.com/en/blog/pretty-is-not-a-website-strategy" rel="noopener noreferrer"&gt;Pretty Is Not a Website Strategy&lt;/a&gt;. A good website should not just look nice. It should solve something.&lt;/p&gt;

&lt;p&gt;That is the part I care about most now: &lt;strong&gt;finding repeated work and turning it into a shorter process&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Websites are still fun, but they are not the whole point
&lt;/h2&gt;

&lt;p&gt;I do not dislike websites. The opposite, actually. A website is still one of the fastest ways to build something visible, useful, and easy for people to access. I like the details: speed, layout, content, design, structure, and the overall product feeling.&lt;/p&gt;

&lt;p&gt;What I do not like is the idea of making the same landing page over and over, changing the logo, colors, and text, and pretending it is a brand-new problem every time.&lt;/p&gt;

&lt;p&gt;When I build a website, the best part is when it becomes more than a presentation. When it gets an admin system, a map, a calculator, data processing, automation, or some internal tool behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  EasyFlex made that clear early
&lt;/h2&gt;

&lt;p&gt;One of the best examples is &lt;a href="https://www.vvitovec.com/en/projects/easyflex" rel="noopener noreferrer"&gt;EasyFlex&lt;/a&gt;. My mom runs her own accounting and tax advisory business, and every month she spends a lot of time entering invoice data into &lt;a href="https://www.abra.eu/flexi/" rel="noopener noreferrer"&gt;ABRA Flexi&lt;/a&gt;, the accounting system she uses.&lt;/p&gt;

&lt;p&gt;On paper, this does not sound dramatic. You open an invoice, read the amount, date, supplier, variable symbol, a few other fields, and enter it into the system. But when you do that again and again, every month, for multiple clients, it becomes a lot of work. Not hard work, just repetitive, slow, and annoying.&lt;/p&gt;

&lt;p&gt;The first version of EasyFlex was not some perfect platform. It was more of a test: what if I could take an invoice, extract the useful data, and prepare it in a way that makes the accounting work much faster?&lt;/p&gt;

&lt;p&gt;Over time I rebuilt parts of it, fixed things, and improved the flow. The result is much more interesting to me than a nice portfolio screenshot: the time my mom spends on that part of the work dropped by more than ten times.&lt;/p&gt;

&lt;p&gt;That is the type of building I like. Not because it looks impressive in a mockup, but because it removes work someone would otherwise repeat again and again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The best features make something easier
&lt;/h2&gt;

&lt;p&gt;I feel the same way with websites. When I worked on Mostky, the most interesting part was not just making a page with text and photos. It was the interactive &lt;a href="https://mostky-web.vercel.app/cs#plots" rel="noopener noreferrer"&gt;2.5D parcel map&lt;/a&gt;, because it helps people understand what is for sale, where it is, and how the plots relate to each other much faster.&lt;/p&gt;

&lt;p&gt;That is the kind of extra feature I enjoy. Not animation just because something should move. I like features that help someone understand the situation faster or make a decision with less effort.&lt;/p&gt;

&lt;p&gt;At that point, the website is mostly the surface. The interesting work is underneath: data, logic, a simple interface, automation, and information flowing in the right order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization is not only a technical thing
&lt;/h2&gt;

&lt;p&gt;When I say I like optimizing, I do not only mean shrinking a bundle or making an API endpoint faster. I like that too, but it is only one layer.&lt;/p&gt;

&lt;p&gt;I mean looking for friction in normal work. Where someone clicks ten times when they should click once. Where someone manually copies data that already exists somewhere else. Where a human waits on a step a system could handle. Where the same small mistake happens every month because nobody built a better process.&lt;/p&gt;

&lt;p&gt;That is much more interesting to me than just asking whether a page looks nice. It should look nice. But if it does not make anything faster, easier, or clearer, then it is mostly decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Right now I want experience
&lt;/h2&gt;

&lt;p&gt;I do not know exactly what I want my final “real job” to be. And I think that is fine. I am still at the stage where I want to try as much as possible: websites, automation, AI tools, internal systems, databases, self-hosting, product work, all of it.&lt;/p&gt;

&lt;p&gt;But the direction is becoming pretty clear. I like building things that are not just nice, but useful. Things that take boring, slow, repeated work and make it faster.&lt;/p&gt;

&lt;p&gt;So yes, I will keep building websites. I just increasingly want there to be something real behind them.&lt;/p&gt;

&lt;p&gt;That is the work I find most interesting now: find a problem, understand it well enough, and build a tool that makes it easier to deal with.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>websites</category>
      <category>tools</category>
      <category>ai</category>
    </item>
    <item>
      <title>Pretty Is Not a Website Strategy</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:48:45 +0000</pubDate>
      <link>https://dev.to/vvitovec/pretty-is-not-a-website-strategy-2d9a</link>
      <guid>https://dev.to/vvitovec/pretty-is-not-a-website-strategy-2d9a</guid>
      <description>&lt;p&gt;A website can look really good and still do almost nothing. That is one of the most common traps with new websites: people spend a lot of energy on colors, animations, photos, and mood, but less on whether a visitor understands the offer in ten seconds.&lt;/p&gt;

&lt;p&gt;Design matters. It is just not the whole product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design is the first impression, not the whole website
&lt;/h2&gt;

&lt;p&gt;A good-looking website helps. When a page feels clean, modern, and trustworthy, people have less reason to close it immediately. That is real value, not some shallow detail.&lt;/p&gt;

&lt;p&gt;The problem starts when visual design becomes the final goal. Then the website can become a nice screenshot for a portfolio, but a weak business tool. The visitor does not know where to start, what the company actually does, who it is for, why it is different, or what to do next.&lt;/p&gt;

&lt;p&gt;Good visuals should support the message, not hide the lack of one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure sells more than effects
&lt;/h2&gt;

&lt;p&gt;A lot of website performance comes from the order of information. First, the offer needs to be clear. Then who it helps. Then why someone should trust it. Then the next step.&lt;/p&gt;

&lt;p&gt;That sounds simple, but it breaks all the time. A homepage has a big slogan and a few nice sections, but no real logic. The visitor gets a few separate impressions, but never moves naturally from problem to solution.&lt;/p&gt;

&lt;p&gt;When I build &lt;a href="https://www.vvitovec.com/en/websites" rel="noopener noreferrer"&gt;websites and landing pages&lt;/a&gt;, I try to understand the business, person, or product behind the page first. A local service needs a different website than a SaaS tool. A portfolio needs a different rhythm again. Using the same template for everyone is fast, but usually the wrong shortcut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy is not filler
&lt;/h2&gt;

&lt;p&gt;Copywriting is one of the most underrated parts of a website. Text is not something you paste in at the end after the design is finished. Text often decides whether the offer makes sense at all.&lt;/p&gt;

&lt;p&gt;One clear sentence can replace three sections of explanation. One vague sentence can make a beautiful layout useless.&lt;/p&gt;

&lt;p&gt;This is not about big marketing phrases. It is about precision. What do you do? Who is it for? What gets better? Why you? What should the visitor do next? If those answers are not visible quickly, design will not rescue the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed and SEO are not boring extras
&lt;/h2&gt;

&lt;p&gt;A slow website loses people before they even see the pretty design. And a website that cannot be found properly is often dependent on manually sending people the link.&lt;/p&gt;

&lt;p&gt;This does not need to become overcomplicated. The basics are fast pages, sensible images, a clean heading structure, useful metadata, and content that answers real questions. For practical performance guidance, &lt;a href="https://web.dev/learn/performance" rel="noopener noreferrer"&gt;web.dev&lt;/a&gt; is useful, and Google has an official &lt;a href="https://developers.google.com/search/docs/fundamentals/seo-starter-guide" rel="noopener noreferrer"&gt;SEO Starter Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These things should not be treated as “later” work. They belong in the base of the website, the same way colors and typography do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch is not the finish line
&lt;/h2&gt;

&lt;p&gt;Another weak point is maintenance. A website launches, everyone is happy for a while, and then it starts getting old. The offer changes. New references appear. Something breaks. Nobody tests the form. The copy stops matching reality. The technology around it keeps moving.&lt;/p&gt;

&lt;p&gt;A website is not a poster. It is a living system.&lt;/p&gt;

&lt;p&gt;That is why I like building things in a more connected way: design, landing pages, web apps, automation, data, and sometimes the backend around it. In some &lt;a href="https://www.vvitovec.com/en/projects" rel="noopener noreferrer"&gt;projects&lt;/a&gt;, the website is not just a business card. It is the entrance into a real workflow. At that point, looking good is only the baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I think about it
&lt;/h2&gt;

&lt;p&gt;When someone wants a new website, the best first question is not “what should it look like?”. A better one is: what should it change?&lt;/p&gt;

&lt;p&gt;Should it bring leads? Explain a complicated service? Make sales easier? Build more trust? Save the team time? Show the work better than the old site?&lt;/p&gt;

&lt;p&gt;Only then does style become useful. Style without direction is just decoration.&lt;/p&gt;

&lt;p&gt;A pretty website is great. But a good website is pretty, clear, fast, maintained, and built around the people who actually use it. I have a short overview of how I build &lt;a href="https://www.vvitovec.com/en/websites" rel="noopener noreferrer"&gt;websites&lt;/a&gt;, or you can just reach out through &lt;a href="https://www.vvitovec.com/en/contact" rel="noopener noreferrer"&gt;contact&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That is basically it. Not every website needs to be a huge application. But almost no website should be just a nice picture with a menu.&lt;/p&gt;

</description>
      <category>websites</category>
      <category>design</category>
      <category>business</category>
    </item>
    <item>
      <title>I turned my old gaming PC into a Linux server</title>
      <dc:creator>Viktor Vítovec</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:07:08 +0000</pubDate>
      <link>https://dev.to/vvitovec/i-turned-my-old-gaming-pc-into-a-linux-server-58gh</link>
      <guid>https://dev.to/vvitovec/i-turned-my-old-gaming-pc-into-a-linux-server-58gh</guid>
      <description>&lt;p&gt;Sometimes an upgrade is not about buying something new. Sometimes the better move is taking the thing that is already sitting there and giving it a better job.&lt;/p&gt;

&lt;p&gt;That is what happened to my old gaming PC. It used to be the center of my gaming setup. Now it is a small home server running databases, backends, and the kinds of things I do not want to pay for as another separate service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I stopped using the desktop
&lt;/h2&gt;

&lt;p&gt;I have been gaming on PC since I was very young, so that machine had a long run. But this year I bought a MacBook Air, and it slowly became my main computer for almost everything: work, personal projects, writing, Codex, and quick ideas away from the desk.&lt;/p&gt;

&lt;p&gt;That changed more than I expected. I did not want to be tied to one setup anymore. I wanted to open the laptop on a train, at school, on a sofa, or wherever else and just continue.&lt;/p&gt;

&lt;p&gt;So the desktop stayed powered off more and more. And when I want to play something now, &lt;a href="https://www.nvidia.com/en-us/geforce-now/" rel="noopener noreferrer"&gt;GeForce NOW&lt;/a&gt; from the Mac is usually enough. The old PC was good for its time, but it was starting to hit performance walls as a gaming machine. As a server, it still made perfect sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  I did not want every small idea to become a subscription
&lt;/h2&gt;

&lt;p&gt;A lot of my projects need some backend, database, auth, or small internal tool. Managed services like Supabase are comfortable and absolutely have their place. But when I build lots of small things for fun, paying separately for every tiny project stops making sense.&lt;/p&gt;

&lt;p&gt;This was not about saving money at all costs. It was more about removing a bad filter from the way I build: &lt;strong&gt;“Is this idea worth another monthly bill?”&lt;/strong&gt; That is a bad question to put in front of creativity.&lt;/p&gt;

&lt;p&gt;Now the server can hold small databases, test services, and backends for projects like &lt;a href="https://www.vvitovec.com/en/projects/easyflex" rel="noopener noreferrer"&gt;EasyFlex&lt;/a&gt;, &lt;a href="https://www.vvitovec.com/en/projects/abra-flexi-ai" rel="noopener noreferrer"&gt;ABRA Flexi AI&lt;/a&gt;, and even the database side of this &lt;a href="https://www.vvitovec.com/en/projects/portfolio-web" rel="noopener noreferrer"&gt;portfolio website&lt;/a&gt;. It also gives me space for more experiments that would otherwise stay in notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Ubuntu was not exactly smooth
&lt;/h2&gt;

&lt;p&gt;The setup itself was not some clean cinematic montage. It was more like a few failed boots, trying to hit the right boot-menu key, dealing with small annoying issues, and finally getting into the &lt;a href="https://ubuntu.com/download" rel="noopener noreferrer"&gt;Ubuntu&lt;/a&gt; installer.&lt;/p&gt;

&lt;p&gt;I kept the setup as minimal as possible. No unnecessary desktop environment, no giant experiment on day one. The goal was simple: &lt;strong&gt;the server should run, host things, and stay out of the way&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That matters. Home infrastructure can easily become another project that eats more time than it saves. I wanted the opposite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloudflare Tunnel beat messing with my router
&lt;/h2&gt;

&lt;p&gt;The next decision was networking. I did not want to expose my home router or deal with port forwarding, public IPs, NAT, and all the usual small traps. I used &lt;a href="https://developers.cloudflare.com/tunnel/" rel="noopener noreferrer"&gt;Cloudflare Tunnel&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;That worked surprisingly well. The tunnel runs on the server, I map a service to a domain, and I do not have to open random things directly through the router. &lt;em&gt;It is boring in exactly the right way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then I started moving hosted things over. Some apps needed different env vars. Some expected a different Node version. Some worked locally and then broke in a completely different way on the server. But that is the normal cost of owning more of the stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  It became a server when I unplugged the monitor
&lt;/h2&gt;

&lt;p&gt;Once the setup was stable enough, I unplugged the monitor. From that point it stopped feeling like “a computer under the desk” and started feeling like a server.&lt;/p&gt;

&lt;p&gt;At first I accessed it through Tailscale, later mostly through SSH with public/private key auth. I also wanted to remove the GPU to save more idle power, but my Ryzen 5 3600 setup will not boot without it. So the GPU unfortunately stays.&lt;/p&gt;

&lt;p&gt;It is not perfect. But it is still much better than letting the whole machine sit unused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex became part of the server workflow
&lt;/h2&gt;

&lt;p&gt;The next obvious step was installing &lt;a href="https://github.com/openai/codex" rel="noopener noreferrer"&gt;Codex&lt;/a&gt;. Not only for working on projects, but also for managing the server itself.&lt;/p&gt;

&lt;p&gt;These days I do not manually SSH into it nearly as much. In the Codex app on my Mac, I have a connection that lets the agent work directly on the Linux server. In &lt;code&gt;AGENTS.md&lt;/code&gt; and a custom skill, I describe what the server is, where projects live, how it should behave, and what it can safely do.&lt;/p&gt;

&lt;p&gt;I sometimes use &lt;a href="https://www.anthropic.com/news/enabling-claude-code-to-work-more-autonomously" rel="noopener noreferrer"&gt;Claude&lt;/a&gt; too, mostly when I want a different angle on UI or frontend work. But for normal server tasks, the interesting part is that Codex can work right next to the infrastructure.&lt;/p&gt;

&lt;p&gt;In practice, that means I can ask it to help with things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moving a small service,&lt;/li&gt;
&lt;li&gt;checking logs,&lt;/li&gt;
&lt;li&gt;preparing a deployment,&lt;/li&gt;
&lt;li&gt;cleaning up &lt;code&gt;/srv/projects&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;setting up a new database or backend quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still need to understand what is happening. That part does not disappear. But I do not have to copy the same commands again and again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from it
&lt;/h2&gt;

&lt;p&gt;I am not saying self-hosting is always better than managed services. It is not. If a project is critical, needs high uptime, has a team behind it, or requires quick support, a managed platform makes a lot of sense.&lt;/p&gt;

&lt;p&gt;But for personal projects, prototypes, small databases, and things I want to build quickly without a small mental tax, having my own Linux server is great. It also fits parts of my &lt;a href="https://www.vvitovec.com/en/websites" rel="noopener noreferrer"&gt;portfolio and website work&lt;/a&gt;, where a small piece of infrastructure does not always need a large platform around it.&lt;/p&gt;

&lt;p&gt;Mostly, I like that the old gaming PC did not become a dust collector. It used to give me performance for games. Now it gives me room to build small things without attaching another account to every idea.&lt;/p&gt;

&lt;p&gt;That is a pretty good second career for an old PC.&lt;/p&gt;

</description>
      <category>selfhosting</category>
      <category>linux</category>
      <category>automation</category>
      <category>codex</category>
    </item>
  </channel>
</rss>
