<?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: Tertiumnon</title>
    <description>The latest articles on DEV Community by Tertiumnon (@tertiumnon).</description>
    <link>https://dev.to/tertiumnon</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%2F983474%2Fcd7376f8-13cc-42a5-942e-2fcb4b017c4d.png</url>
      <title>DEV Community: Tertiumnon</title>
      <link>https://dev.to/tertiumnon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tertiumnon"/>
    <language>en</language>
    <item>
      <title>package.json, package-lock.json, and Semantic Versioning: Why You Need to Understand This</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Wed, 05 Aug 2026 11:44:46 +0000</pubDate>
      <link>https://dev.to/tertiumnon/packagejson-package-lockjson-and-semantic-versioning-why-you-need-to-understand-this-2m9j</link>
      <guid>https://dev.to/tertiumnon/packagejson-package-lockjson-and-semantic-versioning-why-you-need-to-understand-this-2m9j</guid>
      <description>&lt;p&gt;If you've ever run &lt;code&gt;npm install&lt;/code&gt; and then spent an hour and a half debugging why everything works locally but fails in production, this article is for you. That was probably a dependency version issue — the exact problem that proper semantic versioning and lock files solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why versioning exists in the first place
&lt;/h2&gt;

&lt;p&gt;Imagine: you wrote an app using React 18.2.0, and it works perfectly. A month later, React 18.3.0 is released. Should you automatically get this update? It depends on what changed. If it's only bug fixes, it's probably safe. If there's &lt;a href="https://docs.npmjs.com/about-semantic-versioning/" rel="noopener noreferrer"&gt;a breaking change&lt;/a&gt; that breaks half your code — no way.&lt;/p&gt;

&lt;p&gt;That's exactly why &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;semantic versioning (semver)&lt;/a&gt; exists. It's a standard that says: the version number carries information about what changed in the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic versioning: MAJOR.MINOR.PATCH
&lt;/h2&gt;

&lt;p&gt;A version consists of three numbers: &lt;code&gt;MAJOR.MINOR.PATCH&lt;/code&gt;. For example, &lt;code&gt;1.2.3&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MAJOR&lt;/strong&gt; (first digit) — &lt;strong&gt;breaking changes&lt;/strong&gt; that break compatibility. If you update from 1.x.x to 2.x.x, prepare for some code to stop working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MINOR&lt;/strong&gt; (second digit) — &lt;strong&gt;new features&lt;/strong&gt;, but backward-compatible. Updating from 1.2.0 to 1.3.0 should be safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PATCH&lt;/strong&gt; (third digit) — &lt;strong&gt;bug fixes&lt;/strong&gt;. Updating from 1.2.3 to 1.2.4 is just fixes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;The official semver specification&lt;/a&gt; states it clearly: increment MAJOR for incompatible API changes, MINOR for backward-compatible new features, and PATCH for backward-compatible bug fixes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of an exception:&lt;/strong&gt; TypeScript is a counterexample. According to its official stance, &lt;a href="https://dev.to/_d7eb1c1703182e3ce1782/npm-vs-pnpm-vs-yarn-which-package-manager-should-you-use-in-2026-3o3o"&gt;TypeScript explicitly does not follow semver&lt;/a&gt; and introduces breaking changes in MINOR releases. This means upgrading TypeScript from 5.3.0 to 5.4.0 could break your build — and it's formally correct by version number, but not by semver standards. Lesson: even major versions don't guarantee a package follows semver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versioning in package.json: operators and symbols
&lt;/h2&gt;

&lt;p&gt;This is where the fun starts. When you write a version in &lt;code&gt;package.json&lt;/code&gt;, you can use different operators. Each tells npm which updates to look for during installation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exact version (no symbols)
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@prisma/client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6.19.3"&lt;/span&gt;&lt;span class="w"&gt;
&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;This means: install &lt;strong&gt;exactly&lt;/strong&gt; version 6.19.3, no higher, no lower. Pros: absolute predictability. Cons: if 6.19.4 comes out with a critical bug fix, you won't get it until you manually update &lt;code&gt;package.json&lt;/code&gt;. And if you forget about it... well, you get the idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caret (^) — safe updates within major version
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@prisma/client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^6.19.3"&lt;/span&gt;&lt;span class="w"&gt;
&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 caret says: update MINOR and PATCH within the current MAJOR. So 6.19.3 → 6.20.0 → 6.99.9 is okay. But 7.0.0 is not. This is &lt;strong&gt;npm's default&lt;/strong&gt; when you run &lt;code&gt;npm install &amp;lt;package&amp;gt;&lt;/code&gt; without flags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this is good:&lt;/strong&gt; new features (MINOR) should be backward-compatible, so updating is safe. Bug fixes (PATCH) don't need worry at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this can be problematic:&lt;/strong&gt; what if a package violates semver? Or what if a transitive dependency of some obscure library got a breaking change in its "minor" version? That's why lock files exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tilde (~) — only patches
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@prisma/client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~6.19.3"&lt;/span&gt;&lt;span class="w"&gt;
&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 tilde is more conservative: update only PATCH within the current MINOR. So 6.19.3 → 6.19.4 → 6.19.99 is okay. But 6.20.0 is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When this is useful:&lt;/strong&gt; if you're working with a very unstable library where even minor versions can break things. Downside: you miss new features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Greater than (&amp;gt;) and less than (&amp;lt;)
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;4.17.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lodash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;5.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&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;This literally means what it says: install any version strictly greater than 4.17.0 or strictly less than 5.0.0. With &lt;code&gt;&amp;gt;=&lt;/code&gt; and &lt;code&gt;&amp;lt;=&lt;/code&gt; it's the same, but you include the boundary value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When you'd use this:&lt;/strong&gt; rarely. Usually you combine them: &lt;code&gt;"express": "&amp;gt;=4.17.0 &amp;lt;5.0.0"&lt;/code&gt; means "from 4.17.0 to 4.99.99".&lt;/p&gt;

&lt;h3&gt;
  
  
  Equals (=)
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"=18.2.0"&lt;/span&gt;&lt;span class="w"&gt;
&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;This is the same as just &lt;code&gt;"react": "18.2.0"&lt;/code&gt;. Exact version, nothing else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asterisk (*)
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&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;Accept &lt;strong&gt;any&lt;/strong&gt; version. Including 0.x.x-alpha-dev-666. You rarely see this in production code because it's basically a lottery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combining operators
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.npmjs.com/about-semantic-versioning/" rel="noopener noreferrer"&gt;According to npm documentation&lt;/a&gt;, you can combine operators with spaces:&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=18.0.0 &amp;lt;19.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&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;This means: from 18.0.0 to 18.99.99 inclusive. Practically equivalent to &lt;code&gt;^18.0.0&lt;/code&gt;, but explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  package-lock.json: why it's your lifesaver
&lt;/h2&gt;

&lt;p&gt;Here's a scenario without a lock file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Day 1, Machine A (your laptop):&lt;/strong&gt; you write &lt;code&gt;^@prisma/client: 6.19.3&lt;/code&gt; in package.json and run &lt;code&gt;npm install&lt;/code&gt;. The latest version at that moment is 6.19.5, so npm installs it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 2, Machine B (your colleague's machine):&lt;/strong&gt; he clones the repo, sees &lt;code&gt;^6.19.3&lt;/code&gt;, and runs &lt;code&gt;npm install&lt;/code&gt;. But 6.20.0 has just been released — so he gets that instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chaos:&lt;/strong&gt; it works for you, it doesn't for him. Or worse — tests pass locally but fail on CI/CD, where the build happens at yet another point in time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://docs.npmjs.com/about-semantic-versioning/" rel="noopener noreferrer"&gt;package-lock.json&lt;/a&gt; is a file that npm automatically creates and updates when you run &lt;code&gt;npm install&lt;/code&gt;. It records the &lt;strong&gt;exact version of every package and every dependency&lt;/strong&gt; that was installed. When another developer or CI runs &lt;code&gt;npm install&lt;/code&gt;, npm reads this file and installs &lt;strong&gt;the exact same versions&lt;/strong&gt;, regardless of what &lt;code&gt;^&lt;/code&gt; is in package.json.&lt;/p&gt;

&lt;p&gt;This is why lock files are &lt;strong&gt;critical&lt;/strong&gt; to commit to git:&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="c"&gt;# ✓ correct&lt;/span&gt;
git add package.json package-lock.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add dependency"&lt;/span&gt;

&lt;span class="c"&gt;# ✗ wrong&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"package-lock.json"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
git add package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add dependency"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't commit the lock file, every installation becomes a lottery. Imagine you're using &lt;code&gt;^&lt;/code&gt; everywhere, and two weeks pass between your local update and the production server update. 50 new dependency versions are released. The probability that all of them are compatible and no one violated semver — approaches zero.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/wilsonwangdev/lock-files-and-package-manager-migration-a-practical-risk-analysis-2ejn"&gt;According to research&lt;/a&gt;, real packages constantly violate semantic versioning: TypeScript introduces breaking changes in minor releases, PostCSS plugins silently change CSS output. This means lock files are not just convenience — they're your first line of defense.&lt;/p&gt;

&lt;h2&gt;
  
  
  The horror story: when versioning breaks your project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1: Forgotten bug fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You locked &lt;code&gt;~express: 4.17.0&lt;/code&gt; and forgot to update. Version 4.17.5 comes out with a critical security fix. You don't get it because you explicitly wrote &lt;code&gt;~&lt;/code&gt;, not &lt;code&gt;^&lt;/code&gt;. Three months later, hackers exploit that vulnerability. Not fun.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2: Transitive dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You installed &lt;code&gt;some-lib&lt;/code&gt; version 1.2.0, which depends on &lt;code&gt;other-lib: ^2.3.0&lt;/code&gt;. When you installed it, that was 2.3.5. A week later, &lt;code&gt;other-lib@2.4.0&lt;/code&gt; comes out with a breaking change. Your colleague clones the repo, runs &lt;code&gt;npm install&lt;/code&gt; without a lock file — and gets 2.4.0 because the caret allows minor updates. His build breaks, yours works. All because there was no lock file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 3: CI/CD roulette&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On your machine &lt;code&gt;npm install&lt;/code&gt;, on CI machine &lt;code&gt;npm install&lt;/code&gt; (or worse — no lock file). Different versions, different results. Code passes local tests but fails on CI. Then you spend two hours wondering why the same thing works differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different lock files for different package managers
&lt;/h2&gt;

&lt;p&gt;If you're switching from npm to yarn, pnpm, or Bun, it's important to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt; uses &lt;code&gt;package-lock.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;yarn&lt;/strong&gt; uses &lt;code&gt;yarn.lock&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pnpm&lt;/strong&gt; uses &lt;code&gt;pnpm-lock.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bun&lt;/strong&gt; uses &lt;code&gt;bun.lock&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Structurally they differ slightly (&lt;a href="https://dev.to/_d7eb1c1703182e3ce1782/npm-vs-pnpm-vs-yarn-which-package-manager-should-you-use-in-2026-3o3o"&gt;pnpm-lock.yaml&lt;/a&gt;, for instance, is optimized for pnpm's content-addressable storage, and &lt;code&gt;bun.lock&lt;/code&gt; is designed for maximum speed and Node.js ecosystem compatibility), but the essence is the same: they lock exact versions. The key thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never commit lock files from different package managers simultaneously.&lt;/strong&gt; If you're switching from npm to pnpm or Bun, delete the old &lt;code&gt;package-lock.json&lt;/code&gt;:&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="nb"&gt;rm &lt;/span&gt;package-lock.json
pnpm &lt;span class="nb"&gt;install
&lt;/span&gt;git add pnpm-lock.yaml package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Migrate to pnpm"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or when switching to Bun:&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="nb"&gt;rm &lt;/span&gt;package-lock.json yarn.lock pnpm-lock.yaml
bun &lt;span class="nb"&gt;install
&lt;/span&gt;git add bun.lock package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Migrate to bun"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you leave multiple files, they'll conflict and confuse your teammates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common developer mistakes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Adding lock file to .gitignore
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ✗ mistake&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"package-lock.json"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This turns versioning into a casino. Commit lock files &lt;strong&gt;always&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 2: Manually editing lock files
&lt;/h3&gt;

&lt;p&gt;Lock files are automatic. Don't touch them by hand. If you need to update a dependency, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update package-name  &lt;span class="c"&gt;# update within range&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;package-name@desired-version  &lt;span class="c"&gt;# install specific version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 3: Exact versions everywhere
&lt;/h3&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.17.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lodash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.17.21"&lt;/span&gt;&lt;span class="w"&gt;
&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;This is conservative but tedious. You miss bug fixes. Use &lt;code&gt;^&lt;/code&gt; by default — that's what semver is designed for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 4: Wrong lock file handling during branch merges
&lt;/h3&gt;

&lt;p&gt;If you have a merge conflict in &lt;code&gt;package-lock.json&lt;/code&gt;, don't try to resolve it manually:&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="c"&gt;# ✗ wrong: manually editing a lock file&lt;/span&gt;
git add package-lock.json  &lt;span class="c"&gt;# after manual editing&lt;/span&gt;

&lt;span class="c"&gt;# ✓ correct&lt;/span&gt;
git checkout &lt;span class="nt"&gt;--ours&lt;/span&gt; package-lock.json  &lt;span class="c"&gt;# or --theirs&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;  &lt;span class="c"&gt;# npm will automatically update the lock file&lt;/span&gt;
git add package-lock.json package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;npm will sort out the conflict on the next &lt;code&gt;install&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 5: Using npm install instead of npm ci in CI/CD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ✗ may update the lock file&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# ✓ guarantees exact versions&lt;/span&gt;
npm ci  &lt;span class="c"&gt;# clean install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.npmjs.com/cli/ci" rel="noopener noreferrer"&gt;&lt;code&gt;npm ci&lt;/code&gt;&lt;/a&gt; is specifically for CI environments — it installs exactly what's in the lock file without updating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to properly work with versioning
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;^&lt;/code&gt; by default:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^18.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.0"&lt;/span&gt;&lt;span class="w"&gt;
   &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;This lets you get bug fixes and new features automatically but protects from breaking changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Commit the lock file:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git add package.json package-lock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update dependencies through npm, not manually:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm update            &lt;span class="c"&gt;# update within ranges&lt;/span&gt;
   npm outdated          &lt;span class="c"&gt;# see what updates are available&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;npm ci&lt;/code&gt; instead of &lt;code&gt;npm install&lt;/code&gt; in production:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;If you need absolute stability, use &lt;code&gt;~&lt;/code&gt; or exact versions&lt;/strong&gt; — but only for critical dependencies:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"critical-lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~1.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"regular-lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.2.3"&lt;/span&gt;&lt;span class="w"&gt;
   &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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Regularly update dependencies&lt;/strong&gt;, but do it intentionally:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm audit              &lt;span class="c"&gt;# check for vulnerabilities&lt;/span&gt;
   npm audit fix          &lt;span class="c"&gt;# auto-fix&lt;/span&gt;
   npm outdated           &lt;span class="c"&gt;# see available updates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✓ I understand that MAJOR.MINOR.PATCH means breaking/new/fix&lt;/li&gt;
&lt;li&gt;✓ I use &lt;code&gt;^&lt;/code&gt; for flexibility, &lt;code&gt;~&lt;/code&gt; for conservatism&lt;/li&gt;
&lt;li&gt;✓ I commit package-lock.json to git&lt;/li&gt;
&lt;li&gt;✓ I use &lt;code&gt;npm ci&lt;/code&gt; in CI/CD, not &lt;code&gt;npm install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✓ I never manually edit lock files&lt;/li&gt;
&lt;li&gt;✓ I don't commit lock files from different package managers at the same time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's all you need to avoid those soul-crushing hours of debugging "works on my machine but not in production."&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/about-semantic-versioning/" rel="noopener noreferrer"&gt;npm Documentation: Semantic Versioning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;Semantic Versioning Official Specification (semver.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@gfaganli/understanding-npm-semantic-versioning-and-package-lock-json-bc0563c66e39" rel="noopener noreferrer"&gt;Understanding npm Semantic Versioning and package-lock.json by Gulnar Gasanova, Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bytearcher.com/articles/semver-explained-why-theres-a-caret-in-my-package-json/" rel="noopener noreferrer"&gt;Semver Explained: Why There's a Caret in Your package.json by ByteArcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_d7eb1c1703182e3ce1782/npm-vs-pnpm-vs-yarn-which-package-manager-should-you-use-in-2026-3o3o"&gt;pnpm vs npm vs yarn: Which Package Manager Should You Actually Use in 2026? by DEV Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/torp_martin/navigating-lock-files-best-practices-and-tips-5f44"&gt;Navigating Lock Files: Best Practices and Tips by DEV Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/wilsonwangdev/lock-files-and-package-manager-migration-a-practical-risk-analysis-2ejn"&gt;Lock Files and Package Manager Migration: A Practical Risk Analysis by DEV Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/ci" rel="noopener noreferrer"&gt;npm ci Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>SolidJS vs React (2026)</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Mon, 27 Jul 2026 09:16:45 +0000</pubDate>
      <link>https://dev.to/tertiumnon/solidjs-vs-react-2026-3fb0</link>
      <guid>https://dev.to/tertiumnon/solidjs-vs-react-2026-3fb0</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftdor2ffk429uwnv4wjtv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftdor2ffk429uwnv4wjtv.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React remains the de facto frontend standard, but over the past couple of years SolidJS has built a solid reputation as "the framework that got reactivity right." Solid has no virtual DOM, a component runs exactly once, and updates land with surgical precision. That sounds like marketing copy, but it's a direct consequence of the architecture. Let's dig into where SolidJS is genuinely ahead of React on a technical level, what the current 2025-2026 benchmarks and surveys actually say, and — without sugarcoating it — where React still wins by a wide margin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactivity: signals vs the virtual DOM
&lt;/h2&gt;

&lt;p&gt;The core architectural difference sits at the heart of rendering. In React, a component is a function that re-executes in full whenever state changes; the result is diffed against the previous tree via the virtual DOM, and only then are targeted patches applied to the real DOM. It's a convenient model, but it charges a computational tax on every update, even when a single text field deep inside a nested tree is all that changed.&lt;/p&gt;

&lt;p&gt;SolidJS works fundamentally differently: JSX compiles down to plain DOM node creation calls, and state lives in signals (&lt;code&gt;createSignal&lt;/code&gt;) that the component reads once, during the first render. After that, the component function's body never runs again — instead, fine-grained reactive subscriptions are wired up directly: a specific DOM node subscribes straight to a specific signal and updates without any tree comparison whatsoever. Developers call this fine-grained reactivity, as opposed to React's "coarse-grained" component re-rendering. One commenter on the Solid 2.0 beta puts it bluntly: &lt;a href="https://www.infoq.com/news/2026/05/solidjs-2-async/" rel="noopener noreferrer"&gt;Solid has always had the best reactivity model among JS frameworks — true fine-grained updates without a virtual DOM&lt;/a&gt;. That's a bold claim, but it's backed by a concrete architecture that skips the diffing pass entirely, not just the author's personal enthusiasm.&lt;/p&gt;

&lt;p&gt;Signals have long stopped being one framework's party trick — even competitors have adopted the idea. Angular officially acknowledged that its own signal-based reactivity model (&lt;code&gt;signal()&lt;/code&gt;, &lt;code&gt;computed()&lt;/code&gt;, &lt;code&gt;effect()&lt;/code&gt;) was partly inspired by SolidJS: in the &lt;a href="https://github.com/angular/angular/discussions/49685" rel="noopener noreferrer"&gt;Angular Signals RFC&lt;/a&gt;, the Angular team directly credits Solid's creator, Ryan Carniato, for the insight and consultation he provided during the design process. When a framework the size of Angular — one that's been tied to Zone.js and its own change-detection model for a decade — pivots toward Solid's ideas, that says more than any marketing ever could.&lt;/p&gt;

&lt;p&gt;The practical upshot: in React, developers have to manually shield components from unnecessary re-renders, or lean on the React Compiler to do it for them. In Solid, unnecessary re-renders structurally don't exist in the first place — only the DOM node that actually depends on the changed signal gets updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the benchmarks say about performance
&lt;/h2&gt;

&lt;p&gt;The architectural gap shows up directly in synthetic tests. &lt;a href="https://github.com/krausest/js-framework-benchmark" rel="noopener noreferrer"&gt;Stefan Krause's js-framework-benchmark&lt;/a&gt; — the most frequently cited independent frontend framework benchmark — has shown the same pattern for years: SolidJS consistently sits in the top tier of results, right next to "pure" VanillaJS with no framework at all, while React noticeably lags in scenarios with frequent fine-grained updates, large lists, and deeply nested component trees. The &lt;a href="https://listiak.dev/blog/the-state-of-solid-js-in-2026-signals-performance-and-growing-influence" rel="noopener noreferrer"&gt;current state-of-Solid.js-in-2026 overview&lt;/a&gt;, which draws on that benchmark's data, confirms this. According to &lt;a href="https://www.boundev.ai/blog/solidjs-vs-react-performance-comparison" rel="noopener noreferrer"&gt;Boundev's&lt;/a&gt; analysis, in scenarios typical of js-framework-benchmark — creating, updating, and deleting thousands of rows — SolidJS beats React on runtime performance by roughly 50-70%. Worth flagging right away: that's not a universal constant that applies "to any website," it's the result of synthetic, update-heavy tests where the gap between fine-grained reactivity and the virtual DOM is at its most visible.&lt;/p&gt;

&lt;p&gt;On real production interfaces the picture is more modest: most of the time budget there goes to network requests, images, and third-party JS rather than DOM diffing, so the gap tends to be much smaller than in the lab. The React Compiler (more on that below) narrows it further still.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundle size
&lt;/h2&gt;

&lt;p&gt;Fine-grained reactivity gives SolidJS another side benefit: Solid's compiler turns JSX into direct DOM instructions without needing to ship a virtual-DOM diffing engine at runtime, so the framework itself ends up noticeably lighter. According to the &lt;a href="https://listiak.dev/blog/the-state-of-solid-js-in-2026-signals-performance-and-growing-influence" rel="noopener noreferrer"&gt;state-of-Solid.js-in-2026 overview&lt;/a&gt;, Solid's core weighs around &lt;strong&gt;7.6 KB&lt;/strong&gt; minified and gzipped, versus roughly &lt;strong&gt;45 KB&lt;/strong&gt; for React + ReactDOM combined, 38 KB for Vue, and 85+ KB for Angular. The same source, citing a case study from Radware, gives a real production example: for a feature-comparable application, the SolidJS bundle came in around 80 KB versus roughly 290 KB for React. The independent &lt;a href="https://framework-benchmarks.as93.net/solid/" rel="noopener noreferrer"&gt;framework-benchmarks.as93.net&lt;/a&gt; project paints a similar picture — it builds an identical app across different frameworks specifically to compare bundle sizes fairly, and there the gzipped size of a typical weather app built with Solid came out to about 9 KB.&lt;/p&gt;

&lt;p&gt;For projects where fast first load on slow networks and weak devices actually matters, these kilobytes translate directly into milliseconds of Time to Interactive rather than staying a nice number in a report.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Compiler: React strikes back
&lt;/h2&gt;

&lt;p&gt;It would be unfair to describe React the way it looked in 2023. &lt;a href="https://react.dev/blog/2025/10/07/react-compiler-1" rel="noopener noreferrer"&gt;On October 7, 2025, the React team announced the release of React Compiler 1.0&lt;/a&gt; — a build-time compiler that automatically inserts memoization across the component tree, taking over work that used to be done manually with &lt;code&gt;useMemo&lt;/code&gt;, &lt;code&gt;useCallback&lt;/code&gt;, and &lt;code&gt;React.memo&lt;/code&gt;. According to that same official announcement, on real products like the Meta Quest Store the compiler delivered up to a 12% improvement on initial load and cross-page navigation, and sped up individual interactions by more than &lt;strong&gt;2.5x&lt;/strong&gt; — with neutral memory consumption. By 2026, the React Compiler is considered default practice for new React projects, and its rules are baked directly into the recommended &lt;code&gt;eslint-plugin-react-hooks&lt;/code&gt; preset.&lt;/p&gt;

&lt;p&gt;This doesn't erase the fundamental architectural difference — the React Compiler still operates on top of the "re-execute the whole component, but avoid redundant work through memoization" model rather than fine-grained signals. But it meaningfully narrows the practical gap in production, and it takes a big chunk of manual optimization off the developer's plate — optimization that used to be a common source of bugs from forgotten dependencies in &lt;code&gt;useMemo&lt;/code&gt;/&lt;code&gt;useCallback&lt;/code&gt; arrays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer experience: signals are pleasant, but not without surprises
&lt;/h2&gt;

&lt;p&gt;Solid's syntax is deliberately React-like — JSX, hook-like primitives (&lt;code&gt;createSignal&lt;/code&gt;, &lt;code&gt;createEffect&lt;/code&gt;, &lt;code&gt;createMemo&lt;/code&gt;), a component-based approach — so the transition for a React developer feels a lot softer than, say, switching to Vue with its templates and SFCs. But a model without component re-rendering brings its own set of gotchas you won't find in React.&lt;/p&gt;

&lt;p&gt;The main source of beginner mistakes is prop destructuring. In React, &lt;code&gt;const { name } = props&lt;/code&gt; is standard practice. In Solid, props are implemented via getters specifically to enable fine-grained reactivity, so destructuring props "at the door" of a component breaks the reactive link and freezes the value at the moment of the first call. A &lt;a href="https://vladislav-lipatov.medium.com/solidjs-pain-points-and-pitfalls-a693f62fcb4c" rel="noopener noreferrer"&gt;rundown of SolidJS's practical pitfalls&lt;/a&gt; lists several other non-obvious traps: calling an arbitrary function inside &lt;code&gt;createEffect&lt;/code&gt; implicitly subscribes the effect to every signal that function reads (which sometimes calls for wrapping it in &lt;code&gt;untrack&lt;/code&gt;), directives are awkward to reuse across files because of how the TypeScript compiler handles them, and &lt;code&gt;resource&lt;/code&gt; primitives don't support partial updates of nested fields — changing a single object property recreates the whole thing and triggers dependent effects unnecessarily. Nothing fatal, but it takes time to get used to, and none of it is particularly intuitive if your background is purely React.&lt;/p&gt;

&lt;p&gt;On the plus side, there are noticeably fewer React-specific constraints to worry about: you don't need to remember the "rules of hooks" (no conditional or looped hook calls), because Solid's primitives aren't tied to call order inside a render, and a component that runs only once eliminates an entire class of stale-closure bugs that plague &lt;code&gt;useEffect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TypeScript deserves its own mention, and here Solid has a genuinely objective structural edge. Solid is written in TypeScript from the ground up, and types for all its primitives (&lt;a href="https://github.com/solidjs/solid/discussions/980" rel="noopener noreferrer"&gt;&lt;code&gt;createSignal&lt;/code&gt;&lt;/a&gt;, &lt;code&gt;createEffect&lt;/code&gt;, &lt;code&gt;createMemo&lt;/code&gt;, JSX components) ship directly inside the &lt;code&gt;solid-js&lt;/code&gt; package — I checked its &lt;code&gt;package.json&lt;/code&gt; directly via the npm registry, and it has a &lt;code&gt;"types": "types/index.d.ts"&lt;/code&gt; field pointing to bundled declarations; there's simply no separate &lt;code&gt;@types/solid-js&lt;/code&gt; package in the registry. React's situation is different: its own &lt;code&gt;package.json&lt;/code&gt; has no &lt;code&gt;types&lt;/code&gt; field at all — typings live in a separate &lt;code&gt;@types/react&lt;/code&gt; package, which &lt;a href="https://react.dev/learn/typescript" rel="noopener noreferrer"&gt;React.dev itself describes&lt;/a&gt; as sourced from &lt;strong&gt;DefinitelyTyped&lt;/strong&gt;, meaning it's community-maintained rather than maintained by the React team directly. In practice, that means React's types can temporarily fall out of sync with the runtime when new versions ship (a common example being delays in typing new hooks), whereas for Solid, types and runtime are always the same version by construction, because they're literally the same package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ecosystem and market: where React wins decisively
&lt;/h2&gt;

&lt;p&gt;In terms of ecosystem reach and maturity, React is still in a league of its own — there isn't much to argue about here, the gap in its favor is measured in orders of magnitude.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer surveys.&lt;/strong&gt; According to &lt;a href="https://2025.stateofjs.com/en-US/libraries/front-end-frameworks/" rel="noopener noreferrer"&gt;State of JavaScript 2025&lt;/a&gt;, React remains the most-used frontend framework: &lt;a href="https://www.infoq.com/news/2026/03/state-of-js-survey-2025/" rel="noopener noreferrer"&gt;83.6% of respondents&lt;/a&gt; use it at work, compared to about 10% for SolidJS. At the same time, Solid has held the highest satisfaction rating among frameworks for five years running — people who've tried it rarely want to go back to alternatives, but the overwhelming majority of the market is still on React. That popularity has a flip side: the same survey records complaints about React's complexity and about the monetization strategy around Next.js/Vercel — one of the most frequently mentioned pain points in respondent comments. The numbers back this up: Next.js satisfaction in the survey dropped from 68% to 55% amid growing complexity around Server Components and the App Router, and React itself, despite 98% usage reach, draws the most specific complaints about individual APIs — &lt;code&gt;useEffect&lt;/code&gt; got the lowest satisfaction rating of any hook, with dependency-array issues coming in second (21% dissatisfied). React's popularity isn't going anywhere, it remains dominant — but satisfaction with working on it, and with its flagship meta-framework, has dropped noticeably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub.&lt;/strong&gt; The gap in community size is also visible in the repositories: &lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;facebook/react&lt;/a&gt; has around 247,000 stars versus roughly 35,700 for &lt;a href="https://github.com/solidjs/solid" rel="noopener noreferrer"&gt;solidjs/solid&lt;/a&gt; — nearly a sevenfold difference, reflecting the scale of the contributor base and outside attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job market.&lt;/strong&gt; The gap in job listings is even starker than the one in GitHub stars: React has effectively become a baseline requirement in frontend job postings at large companies, while the SolidJS developer community remains niche — there are an order of magnitude fewer openings, and hiring mostly happens through niche boards like &lt;a href="https://rrjanbiah.github.io/solidjs-jobs/" rel="noopener noreferrer"&gt;SolidJS Jobs Listing&lt;/a&gt; rather than mainstream job boards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready-made solutions.&lt;/strong&gt; React has Next.js, Remix/React Router, React Native for mobile, dozens of mature UI kit libraries, and years' worth of ready-made answers on Stack Overflow — things that in Solid often need to be solved yourself or wait for the ecosystem to catch up. SolidStart, the Next.js-equivalent meta-framework for Solid, is still under active development: as of early 2026 it's at &lt;a href="https://listiak.dev/blog/the-state-of-solid-js-in-2026-signals-performance-and-growing-influence" rel="noopener noreferrer"&gt;SolidStart 2.0.0-alpha.2&lt;/a&gt;, while the Next.js ecosystem has years of production usage under its belt at companies like Vercel, Nike, TikTok, and dozens of others. For teams that care about predictable hiring, API stability, and a wide range of ready-made integrations, this is a heavy — and often decisive — argument in favor of React, regardless of the competitor's architectural advantages.&lt;/p&gt;

&lt;p&gt;Native apps deserve a separate note: React has React Native, while Solid has no direct framework equivalent for mobile development. It does have an alternative on a different stack that covers more than just desktop, though. SolidJS pairs well with &lt;a href="https://github.com/tauri-apps/tauri" rel="noopener noreferrer"&gt;Tauri&lt;/a&gt; — a Rust wrapper that renders a frontend built with any web framework, but instead of bundling Chromium like Electron does, it uses the system's WebView, resulting in dramatically smaller binaries and lower memory usage. With the stable release of &lt;a href="https://v2.tauri.app/blog/tauri-20/" rel="noopener noreferrer"&gt;Tauri 2.0&lt;/a&gt;, the framework stopped being a purely desktop tool: it now officially supports iOS and Android from the same codebase — WKWebView on iOS, the system Android WebView on Android — meaning that, in theory, a single Solid app can be built for all five platforms at once (Windows, macOS, Linux, iOS, Android). The mobile side is younger than the desktop side and still a bit rough around the edges — there are quirks around plugins, app signing, and webview peculiarities — but it's already usable in production, not just a proof of concept. There are official and community-maintained Tauri + Solid starter templates (&lt;a href="https://github.com/riipandi/tauri-start-solid" rel="noopener noreferrer"&gt;riipandi/tauri-start-solid&lt;/a&gt;, &lt;a href="https://github.com/ZanzyTHEbar/SolidJSTauri" rel="noopener noreferrer"&gt;ZanzyTHEbar/SolidJSTauri&lt;/a&gt;, and for mobile builds specifically &lt;a href="https://github.com/ZanzyTHEbar/SolidJSTauriMobile" rel="noopener noreferrer"&gt;SolidJSTauriMobile&lt;/a&gt;), and a walkthrough of the Rust + SolidJS + Tauri combo for cross-platform apps has also been published on &lt;a href="https://blog.logrocket.com/rust-solid-js-tauri-desktop-app/" rel="noopener noreferrer"&gt;LogRocket Blog&lt;/a&gt;. Electron is still unmatched in desktop maturity and reach for now — roughly 4.95 million weekly downloads for &lt;code&gt;electron&lt;/code&gt; from npm versus about 1.96 million for &lt;code&gt;@tauri-apps/cli&lt;/code&gt; (npm registry data for July 13-19, 2026) — and it's still slightly ahead on GitHub stars too (122K versus 109K for &lt;a href="https://github.com/tauri-apps/tauri" rel="noopener noreferrer"&gt;tauri-apps/tauri&lt;/a&gt;). But the gap is noticeably narrower than on the web, and the fact that Tauri has grown from a niche desktop project into a full-fledged cross-platform alternative to both Electron and React Native within a couple of years makes Solid + Tauri a genuinely fast-growing choice in exactly the area where SolidJS used to have a structural gap versus React.&lt;/p&gt;

&lt;h2&gt;
  
  
  SolidJS 2.0 and SolidStart: where the framework is headed
&lt;/h2&gt;

&lt;p&gt;The project isn't standing still. &lt;a href="https://www.infoq.com/news/2026/05/solidjs-2-async/" rel="noopener noreferrer"&gt;The SolidJS 2.0 beta shipped on May 15, 2026&lt;/a&gt; — the first major release to make async a first-class citizen directly inside the reactive graph: computations can now return promises directly, and the framework handles suspending and resuming on its own, without wrapping everything in &lt;code&gt;Suspense&lt;/code&gt;. The release also drops the old &lt;code&gt;Suspense&lt;/code&gt; in favor of a simpler &lt;code&gt;Loading&lt;/code&gt; that's only responsible for a subtree's initial readiness, adds &lt;code&gt;action()&lt;/code&gt; and &lt;code&gt;createOptimisticStore&lt;/code&gt; for mutations, and now batches signal writes at the microtask level — a refactor that the framework's creator, &lt;a href="https://www.infoq.com/news/2026/05/solidjs-2-async/" rel="noopener noreferrer"&gt;Ryan Carniato&lt;/a&gt;, defends as the outcome of more than a year spent analyzing alternative approaches, even though part of the community finds the new split-phase &lt;code&gt;createEffect&lt;/code&gt; API clunkier at first glance.&lt;/p&gt;

&lt;p&gt;The current stable line is 1.9.x (according to the &lt;a href="https://listiak.dev/blog/the-state-of-solid-js-in-2026-signals-performance-and-growing-influence" rel="noopener noreferrer"&gt;state-of-Solid.js-in-2026 overview&lt;/a&gt;, the latest version is 1.9.11), so the 2.0 beta isn't yet recommended for new production projects. But the very fact that the framework keeps getting architectural investment, rather than freezing on a "stable but neglected" 1.x, is a good sign for its continued viability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line: when to pick what
&lt;/h2&gt;

&lt;p&gt;Technically, SolidJS really is better than React in a lot of ways: fine-grained reactivity without a virtual DOM eliminates an entire class of re-render problems, synthetic benchmarks like js-framework-benchmark consistently put Solid on par with vanilla JS, and the bundle ends up several times lighter for comparable functionality. All of that is a direct consequence of compiling JSX into fine-grained DOM operations, not empty fan enthusiasm.&lt;/p&gt;

&lt;p&gt;But "technically better" and "the right choice for your team right now" are different questions. The React Compiler has meaningfully narrowed the practical performance gap in production, and React's ecosystem, job market, and sheer volume of ready-made solutions remain an order of magnitude bigger than Solid's. That directly affects development speed and how easy it is to hire for the project — a factor that matters for years, not one sprint. If you're starting a personal or small commercial project where performance and a small bundle really matter, and flexibility in picking libraries isn't a priority — SolidJS is a mature, well-justified choice today. If you're working on a large team, depend on a wide range of ready-made integrations, need React Native, or simply don't want to spend weeks hunting for a rare specialist later — React remains the far safer bet, and the React Compiler only strengthens that bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/news/2026/05/solidjs-2-async/" rel="noopener noreferrer"&gt;SolidJS 2.0 Beta: First-Class Async, Reworked Suspense and Deterministic Batching — InfoQ, May 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://listiak.dev/blog/the-state-of-solid-js-in-2026-signals-performance-and-growing-influence" rel="noopener noreferrer"&gt;The state of Solid.js in 2026: signals, performance, and growing influence — Tomas Listiak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/krausest/js-framework-benchmark" rel="noopener noreferrer"&gt;js-framework-benchmark — Stefan Krause, GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.boundev.ai/blog/solidjs-vs-react-performance-comparison" rel="noopener noreferrer"&gt;SolidJS vs React Performance Comparison — Boundev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://framework-benchmarks.as93.net/solid/" rel="noopener noreferrer"&gt;Framework Benchmarks: Solid.js — as93.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/blog/2025/10/07/react-compiler-1" rel="noopener noreferrer"&gt;React Compiler v1.0 — official React blog, October 7, 2025&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/versions" rel="noopener noreferrer"&gt;React Versions — react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vladislav-lipatov.medium.com/solidjs-pain-points-and-pitfalls-a693f62fcb4c" rel="noopener noreferrer"&gt;SolidJS pain points and pitfalls — Vladislav Lipatov, Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://2025.stateofjs.com/en-US/libraries/front-end-frameworks/" rel="noopener noreferrer"&gt;State of JavaScript 2025: Front-end Frameworks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/news/2026/03/state-of-js-survey-2025/" rel="noopener noreferrer"&gt;State of JavaScript 2025: Survey Reveals a Maturing Ecosystem — InfoQ, March 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;facebook/react — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/solidjs/solid" rel="noopener noreferrer"&gt;solidjs/solid — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rrjanbiah.github.io/solidjs-jobs/" rel="noopener noreferrer"&gt;SolidJS Jobs Listing &amp;amp; SolidJS Developers/Freelancers Listing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tauri-apps/tauri" rel="noopener noreferrer"&gt;tauri-apps/tauri — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/riipandi/tauri-start-solid" rel="noopener noreferrer"&gt;riipandi/tauri-start-solid — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ZanzyTHEbar/SolidJSTauri" rel="noopener noreferrer"&gt;ZanzyTHEbar/SolidJSTauri — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ZanzyTHEbar/SolidJSTauriMobile" rel="noopener noreferrer"&gt;ZanzyTHEbar/SolidJSTauriMobile — GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/rust-solid-js-tauri-desktop-app/" rel="noopener noreferrer"&gt;Rust, SolidJS, and Tauri: Create a cross-platform desktop app — LogRocket Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v2.tauri.app/blog/tauri-20/" rel="noopener noreferrer"&gt;Tauri 2.0 Stable Release — official Tauri blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/angular/angular/discussions/49685" rel="noopener noreferrer"&gt;RFC: Angular Signals — angular/angular discussion on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://api.npmjs.org/downloads/point/last-week/@tauri-apps/cli" rel="noopener noreferrer"&gt;@tauri-apps/cli — npm download stats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://api.npmjs.org/downloads/point/last-week/electron" rel="noopener noreferrer"&gt;electron — npm download stats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/learn/typescript" rel="noopener noreferrer"&gt;Using TypeScript — react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.solidjs.com/configuration/typescript" rel="noopener noreferrer"&gt;TypeScript — SolidJS Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.npmjs.org/solid-js/latest" rel="noopener noreferrer"&gt;solid-js — npm registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.npmjs.org/react/latest" rel="noopener noreferrer"&gt;react — npm registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://2025.stateofreact.com/en-US/features/" rel="noopener noreferrer"&gt;State of React 2025: Features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>solidjs</category>
      <category>react</category>
    </item>
    <item>
      <title>minimal css framework</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Sat, 07 Jun 2025 05:17:44 +0000</pubDate>
      <link>https://dev.to/tertiumnon/minimal-css-framework-2453</link>
      <guid>https://dev.to/tertiumnon/minimal-css-framework-2453</guid>
      <description></description>
      <category>frontend</category>
      <category>webdev</category>
      <category>minimalism</category>
    </item>
    <item>
      <title>Cooking with TypeScript enums</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Wed, 26 Mar 2025 16:42:35 +0000</pubDate>
      <link>https://dev.to/tertiumnon/cooking-with-typescript-enums-4822</link>
      <guid>https://dev.to/tertiumnon/cooking-with-typescript-enums-4822</guid>
      <description>&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%2F411fllkw85e63nr58iww.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%2F411fllkw85e63nr58iww.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Periodically I hear that something wrong with TypeScript enums. But if you understand how it works - it's not an issue for you.&lt;/p&gt;

&lt;p&gt;The usage is very simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Moderator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we have a good news here - we can use string values in TypeScript! For instance, C# enums can't work with string values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;UserRole&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Moderator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pros and cons of enums
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Excessive JavaScript code after compilation
&lt;/h3&gt;

&lt;p&gt;I think the claim that TypeScript enums produce excessive JavaScript code is somewhat overstated. Have you ever wondered how much code your compiler generates? I highly doubt it. But when it comes to types, you somehow think differently. Don't you find that strange?&lt;/p&gt;

&lt;p&gt;Let's take a look on generated JS code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;None&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;None&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks ugly but it doesn't produce any "terrible" effects.&lt;/p&gt;

&lt;p&gt;We can continue our investigation. Let's create a file with &lt;code&gt;enum&lt;/code&gt; and a file with &lt;code&gt;type&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RoleType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And than we can import both files to apply values from both kinds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserRole&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./enum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RoleType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Moderator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roleType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RoleType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result in JS will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;enum_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./enum&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;enum_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Moderator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;roleType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moderator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see here that &lt;code&gt;enum&lt;/code&gt; produce a variable with values but &lt;code&gt;type&lt;/code&gt; don't. It means that &lt;code&gt;enum&lt;/code&gt; don't repeat itself. It's an Object with properties.&lt;/p&gt;

&lt;p&gt;Let's create a class - another TypeScript feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you will get the next compiled JS code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="cm"&gt;/** @class */&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks ugly too, isn't it? More code, more problems? I don't think so!&lt;/p&gt;

&lt;p&gt;I worked with many projects and teams, and you should know that very common problems are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Over-complicated code (ignoring all principles of clean coding)&lt;/li&gt;
&lt;li&gt;Inefficient code (CPU and memory loading)&lt;/li&gt;
&lt;li&gt;Environment issues (caching invalidation, network loading, etc.)&lt;/li&gt;
&lt;li&gt;Legacy dependencies (security issues, difficulties with upgrading)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-obviousness of usage
&lt;/h3&gt;

&lt;p&gt;The most common example of incorrect use of &lt;code&gt;enums&lt;/code&gt; is shown in the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;UserRole&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Moderator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is a real problem here. Problem for those who don't understand some JS and TS nuances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// you will get a logically incorrect result&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ROLES_VALUES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ["Admin", "Moderator", 0, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the reason why &lt;strong&gt;we always must use values for enums&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A good part of &lt;code&gt;enums&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Enums&lt;/code&gt; can help you create arrays and objects that we might need in other parts of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isRoleValueCorrect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ROLE_VALUES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can create options for select:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}));&lt;/span&gt;
&lt;span class="cm"&gt;/*
[{
  "label": "None",
  "value": ""
}, {
  "label": "Moderator",
  "value": "moderator"
}, {
  "label": "Admin",
  "value": "admin"
}] 
 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;TypeScript &lt;code&gt;enums&lt;/code&gt; is not a "bad" feature.&lt;/p&gt;

&lt;p&gt;In some case it's confusing but only if you don't understand how to work with that.&lt;/p&gt;

&lt;p&gt;This is convenient if you want to create related data structures.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>enums</category>
    </item>
    <item>
      <title>A minimum of books that should be read by a novice or experienced programmer</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Wed, 26 Mar 2025 12:57:17 +0000</pubDate>
      <link>https://dev.to/tertiumnon/a-minimum-of-books-that-should-be-read-by-a-novice-or-experienced-programmer-4hpb</link>
      <guid>https://dev.to/tertiumnon/a-minimum-of-books-that-should-be-read-by-a-novice-or-experienced-programmer-4hpb</guid>
      <description>&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%2Ff899miuv13qubiq9dx7p.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%2Ff899miuv13qubiq9dx7p.png" alt="Intro" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below a small list of books that I can personally recommend for reading to all programmers, including beginners. As it usually happens that I bought, I sell it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computer Science fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Computer Science Distilled (Wladston Ferreira Filho)
&lt;/h3&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%2F90rlmd5salhiupxqzsix.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%2F90rlmd5salhiupxqzsix.png" alt="Computer Science Distilled" width="311" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an super-"based" book which is well-suited for beginners, particularly for those who have no specialized education.&lt;/p&gt;

&lt;h3&gt;
  
  
  Harvard CS50 video course
&lt;/h3&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%2Fe2wnmbf931jwmilxwi7h.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%2Fe2wnmbf931jwmilxwi7h.png" alt="Harvard CS50" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a book, but perhaps the best that you can find for training a base. This is a magnificent Harvard course, on the example of which you will understand why people seek to get to study in places such as Harvard. You can watch this course &lt;a href="https://www.youtube.com/channel/UCcabW7890RKJzL968QWEykA" rel="noopener noreferrer"&gt;online&lt;/a&gt; absolutely free.&lt;/p&gt;

&lt;p&gt;Also, you can earn a certificate on &lt;a href="https://www.edx.org/cs50" rel="noopener noreferrer"&gt;edx.org&lt;/a&gt; or &lt;a href="https://pll.harvard.edu/course/cs50-introduction-computer-science" rel="noopener noreferrer"&gt;on the Harvard website&lt;/a&gt;. The course is regularly updated, so if you started, it is better to finish in the same year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Object-Oriented Thought Process (Matt Weisfeld)
&lt;/h3&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%2F224kf7aposeonl7e37vr.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%2F224kf7aposeonl7e37vr.png" alt="Object-Oriented Thought Process" width="370" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would describe this book as the initial one for those who want to use the OOP in their work. I know that this book is not very popular, but it personally helped me in due time to "set up" some concepts in my head.&lt;/p&gt;

&lt;h3&gt;
  
  
  Head First Design Patterns (Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra)
&lt;/h3&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%2F95n70al28xn0ak021unv.jpg" 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%2F95n70al28xn0ak021unv.jpg" alt="Head First Design Patterns" width="415" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two versions of these books - one of them contains illustrations for better understanding. Understanding the patterns will allow you to structure various approaches in your head and communicate in the same language with other programmers, choosing solutions for certain problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean Code (Robert Martin)
&lt;/h3&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%2F52387uvs93r8xr96otkb.jpg" 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%2F52387uvs93r8xr96otkb.jpg" alt="Clean Code" width="363" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the book you will find a set of rules that will help you write understandable for yourself and, which is much more important in large companies, a code understood for other programmers. The sooner you read this book, the better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Driven Development: By Example (Kent Beck)
&lt;/h3&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%2Fijwqwhao7fk8phfekt2e.jpg" 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%2Fijwqwhao7fk8phfekt2e.jpg" alt="Test Driven Development" width="381" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes programmers neglect testing (which is bad). The book will inspire you to write tests, or at least give food for thought.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithms and data structures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Grokking Algorithms (Aditya Y. Bhargava)
&lt;/h3&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%2Fydu8893pa9vmg04cvd1w.jpg" 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%2Fydu8893pa9vmg04cvd1w.jpg" alt="Grokking Algorithms" width="382" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The book gives basic ideas about the algorithms and data structures. The book is loved by many for its simplicity, with which the author explains key principles. If you read, understand and implement everything that is in this book, then you should not have problems with the next book. It is recommended to read the updated (fixed) version of the book.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cracking the Coding Interview (Gayle Laakmann McDowell)
&lt;/h3&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%2Fmtyo580qlyo3uhovsnx9.jpg" 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%2Fmtyo580qlyo3uhovsnx9.jpg" alt="Cracking the Coding Interview" width="336" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essentially, this book is intended for those who are going through interviews at major technology companies. A lot of material is dedicated to the main section – algorithmic.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  System Design (Alex Xu)
&lt;/h3&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%2Ffph8cbeb90bgq3a9uuuo.jpg" 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%2Ffph8cbeb90bgq3a9uuuo.jpg" alt="System Design" width="320" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A well-structured book that is often recommended for reading before undergoing interviews. Numerous diagrams, describing various 'IT-related' things, by the same author can be found online.&lt;/p&gt;

&lt;h2&gt;
  
  
  High Load
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Designing Data-Intensive Applications (Martin Kleppmann)
&lt;/h3&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%2Fbr5kibk4awefyjk3e6fx.jpg" 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%2Fbr5kibk4awefyjk3e6fx.jpg" alt="Designing Data-Intensive Applications" width="366" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Famous "book with the boar", one of the fundamental books for a programmer who wants to proudly call themselves a Software Engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Software Engineering at Google (Titus Winters, Tom Manshreck, Hyrum Wright)
&lt;/h3&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%2Falzl83u6ibkr9umi1tau.jpg" 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%2Falzl83u6ibkr9umi1tau.jpg" alt="Software Engineering at Google" width="366" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The book provides general insights into development at tech giants like Google. You can learn how to be a good manager, hire engineers and evaluate their performance, test, scale, and decide on tools to use – a lot of useful content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agile Estimating and Planning (Mike Cohn)
&lt;/h3&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%2Faiaalj2gtuhlla9d6can.jpg" 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%2Faiaalj2gtuhlla9d6can.jpg" alt="Agile Estimating and Planning" width="363" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my opinion, the book is somewhat verbose. However, it contains very detailed descriptions of team interactions working with Agile methodology, which you'll start to understand and use better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;It would be interesting to see your minimum set of books in the comments. If there are any remarks, I'll try to improve the article or publish an updated version later.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>books</category>
    </item>
    <item>
      <title>You don't need Redux</title>
      <dc:creator>Tertiumnon</dc:creator>
      <pubDate>Wed, 12 Mar 2025 11:11:55 +0000</pubDate>
      <link>https://dev.to/tertiumnon/you-dont-need-redux-462b</link>
      <guid>https://dev.to/tertiumnon/you-dont-need-redux-462b</guid>
      <description>&lt;p&gt;As you're likely aware, Dan Abramov published a post titled "You Might Not Need Redux" back in 2016. Yet, here we are in 2025, and it appears that many projects and job postings haven't adapted. Sadly, not much has changed.&lt;/p&gt;

&lt;p&gt;The Yandex expert in the video below demonstrates that you can thrive without using Redux.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please, be aware the video contains Russian language and auto-generated English subtitles.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/JHSslO7EJZc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
