Skip to content

Commit fd5834c

Browse files
committed
regenerate site with latest SSG
1 parent d13dc9f commit fd5834c

33 files changed

Lines changed: 493 additions & 607 deletions

File tree

html/adding_h-card_to_this_site,_and_scope_creep.html renamed to html/adding_h-card_to_this_site_and_scope_creep.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link rel="stylesheet" href="/css/typography.css">
1212
<link rel="stylesheet" href="/css/vars.css">
1313
<link rel="stylesheet" href="/css/styles.css">
14-
<link rel="stylesheet" href="/css/post.css">
14+
<link rel="stylesheet" href="/css/post.css">
1515
</head>
1616
<body>
1717
<article class="h-entry">
@@ -59,7 +59,7 @@ <h2>Conclusion</h2>
5959
<p>It&rsquo;s always interesting to see how software takes on a life of it&rsquo;s own as it&rsquo;s used more and more.</p>
6060

6161
<time class="published-date dt-published" datetime="2023-01-16 21:34:45 -0500 EST">Jan 16, 2023</time>
62-
<a rel="permalink" href="html/adding_h-card_to_this_site,_and_scope_creep.html" class="u-url">Permalink</a>
62+
<a rel="permalink" href="html/adding_h-card_to_this_site_and_scope_creep.html" class="u-url">Permalink</a>
6363
<a rel="author" class="p-author" href="https://RyanNickel.com">Ryan Nickel</a>
6464
</main>
6565
</article>

html/creating_homebrew_package_for_staticsitegenerator_distribution.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link rel="stylesheet" href="/css/typography.css">
1212
<link rel="stylesheet" href="/css/vars.css">
1313
<link rel="stylesheet" href="/css/styles.css">
14-
<link rel="stylesheet" href="/css/post.css">
14+
<link rel="stylesheet" href="/css/post.css">
1515
</head>
1616
<body>
1717
<article class="h-entry">

html/creating_my_ideal_react_native_projects_with_typescript_eslint,_prettier_and_vscode.html renamed to html/creating_my_ideal_react_native_projects_with_typescript_eslint_prettier_and_vscode.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link rel="stylesheet" href="/css/typography.css">
1212
<link rel="stylesheet" href="/css/vars.css">
1313
<link rel="stylesheet" href="/css/styles.css">
14-
<link rel="stylesheet" href="/css/post.css">
14+
<link rel="stylesheet" href="/css/post.css">
1515
</head>
1616
<body>
1717
<article class="h-entry">
@@ -315,7 +315,7 @@ <h2>tsconfig.json</h2>
315315
<p>I&rsquo;ve created a <a href="https://github.com/mrnickel/ReactNativeTypeScriptConfigDemo">demo project on GitHub</a>. If you have any recommendations on how I can make this better please feel free to submit a PR!</p>
316316

317317
<time class="published-date dt-published" datetime="2019-06-04 15:41:58 -0400 EDT">Jun 04, 2019</time>
318-
<a rel="permalink" href="html/creating_my_ideal_react_native_projects_with_typescript_eslint,_prettier_and_vscode.html" class="u-url">Permalink</a>
318+
<a rel="permalink" href="html/creating_my_ideal_react_native_projects_with_typescript_eslint_prettier_and_vscode.html" class="u-url">Permalink</a>
319319
<a rel="author" class="p-author" href="https://RyanNickel.com">Ryan Nickel</a>
320320
</main>
321321
</article>

html/docker_and_charles.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link rel="stylesheet" href="/css/typography.css">
1212
<link rel="stylesheet" href="/css/vars.css">
1313
<link rel="stylesheet" href="/css/styles.css">
14-
<link rel="stylesheet" href="/css/post.css">
14+
<link rel="stylesheet" href="/css/post.css">
1515
</head>
1616
<body>
1717
<article class="h-entry">

html/fall_or_dodge_in_hell_a_promising_start_that_got_lost_in_the_digital_abyss.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ <h1 class="p-name">Fall; Or, Dodge in Hell: A Promising Start That Got Lost in t
3535
<p>Rating this one? Well, I&rsquo;d say it&rsquo;s a solid 2.5 out of 5 stars.</p>
3636

3737
<time class="published-date dt-published" datetime="2023-05-31 13:12:16 -0400 EDT">May 31, 2023</time>
38-
<a rel="permalink" href="html/fall;_or,_dodge_in_hell:_a_promising_start_that_got_lost_in_the_digital_abyss.html" class="u-url">Permalink</a>
38+
<a rel="permalink" href="html/fall_or_dodge_in_hell_a_promising_start_that_got_lost_in_the_digital_abyss.html" class="u-url">Permalink</a>
3939
<a rel="author" class="p-author" href="https://RyanNickel.com">Ryan Nickel</a>
4040
</main>
4141
</article>

html/hello_world.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link rel="stylesheet" href="/css/typography.css">
1212
<link rel="stylesheet" href="/css/vars.css">
1313
<link rel="stylesheet" href="/css/styles.css">
14-
<link rel="stylesheet" href="/css/post.css">
14+
<link rel="stylesheet" href="/css/post.css">
1515
</head>
1616
<body>
1717
<article class="h-entry">
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
7+
8+
<title>RyanNickel.com - How NPM's Defaults Set You Up for Failure</title>
9+
10+
<link rel="stylesheet" href="//unpkg.com/sanitize.css">
11+
<link rel="stylesheet" href="/css/typography.css">
12+
<link rel="stylesheet" href="/css/vars.css">
13+
<link rel="stylesheet" href="/css/styles.css">
14+
<link rel="stylesheet" href="/css/post.css">
15+
</head>
16+
<body>
17+
<article class="h-entry">
18+
<header>
19+
<h1 class="p-name">How NPM's Defaults Set You Up for Failure</h1>
20+
</header>
21+
22+
<main class="e-content">
23+
<p>In software development, consistency and stability are critical — especially when managing dependencies. However, NPM&rsquo;s default behavior when installing packages—using the caret (<code>^</code>) in <code>package.json</code> — creates a fragile environment that often leads to frustrating issues for developers. Idempotent and reproducible dependency management should be the standard experience by default, but NPM&rsquo;s use of <code>^</code> undermines this goal.</p>
24+
25+
<p>Here&rsquo;s why it&rsquo;s time to rethink the default use of caret versioning in NPM, and how it sets developers up for future pain, particularly given the complexities of semantic versioning (semver).</p>
26+
27+
<h2>Why ^ Versioning Isn’t a Safe Default</h2>
28+
29+
<p>The caret (<code>^</code>) prefix in NPM allows minor and patch version updates automatically. For example, if you run:</p>
30+
31+
<pre><code>npm install lodash
32+
</code></pre>
33+
34+
<p>NPM adds the following entry to your <code>package.json</code>:</p>
35+
36+
<pre><code>&quot;lodash&quot;: &quot;^4.17.21&quot;
37+
</code></pre>
38+
39+
<p>This means that any future installation can upgrade the <code>lodash</code> dependency to anything below <code>5.0.0</code>. While this aims to provide developers with bug fixes and new features without manual intervention, it introduces significant risks: <strong>unexpected changes</strong>, <strong>hidden regressions</strong>, and <strong>version incompatibilities</strong> in complex projects.</p>
40+
41+
<h2>1. Semver is Hard—and NPM Makes it Harder</h2>
42+
43+
<p>Semantic versioning (semver) is designed to make versioning predictable: major versions introduce breaking changes, minor versions add features, and patches fix bugs. However, not all packages in the JavaScript ecosystem strictly adhere to semver rules. Accidental breaking changes are common, even in minor or patch versions.</p>
44+
45+
<p>By defaulting to <code>^</code>, NPM shifts the burden of semver compliance onto developers, who must constantly monitor updates to avoid potential breakages. This behavior creates unpredictable outcomes that often surface in production or CI pipelines. <strong>NPM’s default makes the promise of semver nearly impossible to uphold</strong>, resulting in wasted time troubleshooting issues that stem from unintended updates.</p>
46+
47+
<h2>2. A Reproducible Developer Experience Should Be the Default</h2>
48+
49+
<p>An idempotent development environment ensures that every code checkout and dependency installation yields the same behavior, regardless of when or where it happens. This level of consistency is essential for stable CI/CD pipelines, reliable production releases, and seamless collaboration across teams.</p>
50+
51+
<p>Other ecosystems, such as <a href="https://go.dev/">Go</a> and <a href="https://www.nuget.org/">NuGet</a>, use exact versioning to prevent dependency drift. In Go, the <code>go.mod</code> file locks dependencies to specific versions, ensuring builds are reproducible every time. NuGet favors deterministic package management for similar reasons. These approaches prioritize stability by ensuring nothing changes unless a developer explicitly updates a version.</p>
52+
53+
<p>In contrast, NPM&rsquo;s default caret (<code>^</code>) versioning can lead to differing versions on different machines. Reproducing bugs becomes a nightmare when dependencies shift between development, CI, and production environments, making stability difficult to maintain.</p>
54+
55+
<h2>3. ^ is a Time Bomb Waiting to Go Off</h2>
56+
57+
<p>The flexibility provided by ^ introduces risks that compound over time. Here’s why:</p>
58+
59+
<ol>
60+
<li><strong>Invisible Updates</strong>: Dependencies can be updated silently, resulting in unexpected issues.</li>
61+
<li><strong>Version Conflicts</strong>: As the dependency tree grows, conflicts arise between direct and transitive dependencies.</li>
62+
<li><strong>CI Pipeline Failures</strong>: Even if code works locally, a new patch version of a dependency may cause unexpected CI build failures.</li>
63+
</ol>
64+
65+
<p>These issues could be avoided by making exact versioning the default. Developers should have control over when to upgrade dependencies, whether through planned reviews, automated tools like Dependabot, or manually tested patch releases.</p>
66+
67+
<h2>4. The Case for <code>--save-exact</code> as the Default</h2>
68+
69+
<p>NPM should default to <code>--save-exact</code> behavior, where every dependency is locked to the precise version installed. This would look like:</p>
70+
71+
<pre><code>&quot;lodash&quot;: &quot;4.17.21&quot;
72+
</code></pre>
73+
74+
<p>This ensures that the versions used during development are identical across all environments. Developers can still upgrade dependencies intentionally, but only when they are ready to manage the risks. This approach reduces reactive debugging and ensures a <strong>reproducible</strong> development experience by default.</p>
75+
76+
<h2>How to Implement an Idempotent NPM Workflow</h2>
77+
78+
<p>If NPM doesn’t change its default behavior, you can take these steps to enforce stability in your projects:</p>
79+
80+
<ol>
81+
<li><strong>Use npm install <code>--save-exact</code></strong>. Set this behavior as the default:
82+
<code>npm config set save-exact true</code></li>
83+
<li><strong>Leverage <code>npm ci</code> for CI pipelines</strong>. This ensures only the versions listed in <code>package-lock.json</code> are installed, preventing unexpected updates.</li>
84+
<li><strong>Use automated tools to manage updates</strong>. Tools like Dependabot can help you control upgrades in a systematic manner.</li>
85+
</ol>
86+
87+
<h2>Conclusion</h2>
88+
89+
<p>NPM&rsquo;s default use of the caret (<code>^</code>) for versioning creates more problems than it solves. In an ideal world, semantic versioning would work flawlessly, but in reality, <strong>semver is hard</strong> — and NPM’s current behavior makes it even harder by encouraging version drift and unpredictable builds. A reproducible, idempotent developer experience should be the default, not the exception.</p>
90+
91+
<p>By shifting to <code>--save-exact</code>, NPM would align with practices of more stable ecosystems like Go and NuGet. This change would empower developers to upgrade dependencies on their own terms, reducing surprises and enabling smoother workflows. The minor inconvenience of managing updates manually is a small price to pay for long-term stability and consistency.</p>
92+
93+
<p>It’s time for NPM to rethink its defaults and prioritize stability—because predictable software is <strong>better software</strong>.</p>
94+
95+
<time class="published-date dt-published" datetime="2024-10-22 19:06:32 -0400 EDT">Oct 22, 2024</time>
96+
<a rel="permalink" href="html/how_npm39s_defaults_set_you_up_for_failure.html" class="u-url">Permalink</a>
97+
<a rel="author" class="p-author" href="https://RyanNickel.com">Ryan Nickel</a>
98+
</main>
99+
</article>
100+
101+
<footer class="h-card">
102+
<img class="u-photo" src="/img/headshot.png" alt="headshot">
103+
<span class="p-name">Ryan Nickel</span>
104+
<a class="hidden u-url" rel="me" href="https://RyanNickel.com">https://RyanNickel.com</a>
105+
106+
<ul>
107+
<li><a rel="me" href="https://twitter.com/rnickel" class="u-url">Twitter</a></li>
108+
<li><a rel="me" href="https://github.com/mrnickel" class="u-url">GitHub</a></li>
109+
<li><a href="/about.html">About</a></li>
110+
<li><a rel="me" href="https://indieweb.social/@mrnickel" class="u-url">Mastodon</a></li>
111+
<li><a href="/rss.xml">RSS</a></li>
112+
</ul>
113+
114+
<p>Made with &hearts; by <span class="p-given-name">Ryan</span> <span class="p-family-name">Nickel</span> in <span class="p-locality">Toronto</span>, <span>Canada</span></p>
115+
116+
<img src="/img/toronto-icon-sm.png" alt="Toronto Icon" class="cityicon">
117+
118+
<p>Generated with my super awesome <a href="https://github.com/mrnickel/StaticSiteGenerator">StaticSiteGenerator</a></p>
119+
</footer>
120+
121+
<script>
122+
(function (i, s, o, g, r, a, m) {
123+
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
124+
(i[r].q = i[r].q || []).push(arguments)
125+
}, i[r].l = 1 * new Date(); a = s.createElement(o),
126+
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
127+
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
128+
129+
ga('create', 'UA-35684132-1', 'auto');
130+
ga('send', 'pageview');
131+
132+
</script>
133+
134+
</body>
135+
</html>

0 commit comments

Comments
 (0)