<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Numerical Bits]]></title><description><![CDATA[The official development blog of stdlib, the fundamental numerical computing library for JavaScript and the Web.]]></description><link>https://blog.stdlib.io/</link><image><url>https://blog.stdlib.io/favicon.png</url><title>Numerical Bits</title><link>https://blog.stdlib.io/</link></image><generator>Ghost 5.83</generator><lastBuildDate>Wed, 12 Aug 2026 17:33:13 GMT</lastBuildDate><atom:link href="https://blog.stdlib.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Your AI Policy Doesn't Have to Apply to You]]></title><description><![CDATA[Not applying your own rules to yourself isn't always hypocrisy. Sometimes it's just correct.]]></description><link>https://blog.stdlib.io/your-ai-policy-doesnt-have-to-apply-to-you/</link><guid isPermaLink="false">6a7c76c381c4de9ae6e8755e</guid><category><![CDATA[Developer Relations]]></category><category><![CDATA[Governance]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Wed, 12 Aug 2026 14:01:46 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/08/ai_policy_does_not_apply_to_you_og.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/08/ai_policy_does_not_apply_to_you_og.png" alt="Your AI Policy Doesn&apos;t Have to Apply to You"><p>A confession: stdlib doesn&apos;t have an AI-use policy.</p>
<p>It isn&apos;t for lack of trying. There&apos;s an open RFC proposing guidance on AI usage&#x2014;citations to prior art, disclosure requirements, a carve-out for &quot;good first issue&quot;<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>&#x2014;and a draft PR with the policy text, both of which are from December 2025.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> Both are still open. Both are still drafts.</p>
<p>It&apos;s not because AI usage is hypothetical here, either. We&apos;ve had stdlib core contributors participating in <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/?ref=blog.stdlib.io">METR&apos;s randomized trial</a> on AI&apos;s effect on experienced open-source developers since 2025. Philipp Burckhardt, one of stdlib&apos;s co-maintainers, wrote up <a href="https://blog.stdlib.io/reflection-on-the-metr-study-2025/">his experience</a> on the project blog, including which tools he uses and how his workflow changed.<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> More recently, Karan Anand described <a href="https://blog.stdlib.io/the-codebase-is-the-prompt/">using the codebase itself as the prompt</a>.</p>
<p>So: we use these tools, we&apos;ve said so in public, and (beyond some check boxes in our PR template) we still haven&apos;t codified what we expect from anyone else. We&apos;ve gotten stuck, and one of the sticking points has been an obvious one&#x2014;discomfort with publishing a rule we&apos;re not going to hold ourselves to.</p>
<p>This is a real objection. It&apos;s also, I&apos;ve come to think, the wrong one, and we&apos;re not the only project stalling out on it. The question isn&apos;t <em>whether</em> AI is being used on this project. It&apos;s whether there&apos;s anything written down that a contributor can read.</p>
<p>Plenty of projects got past this. Melissa Weber Mendon&#xE7;a keeps a running catalog of what&apos;s been published;<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup> Kate Holterhoff&apos;s RedMonk survey was up to eighty-six policies as of April 2026, dimensionalized by stance and primary concern;<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup> CHAOSS&apos;s AI-alignment working group runs a companion list with an incident-and-discussion layer.<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup></p>
<p>Given the scope of the discourse around AI usage in open source, this is a strikingly small corpus&#x2014;and a young one.<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup> Nobody is late to a settled consensus here. As James Fredley put it, after a tier-by-tier read from the primary documents: &quot;there is no single industry-wide standard yet.&quot;<sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup></p>
<p>What the policies themselves agree on is narrower than it first looks. Stance splits three ways&#x2014;permissive, ban, undecided&#x2014;and the stated concerns split at least three ways again: code quality, licensing liability, and ethics. Where they <em>do</em> line up is on something small and specific: <strong>contributors are responsible for understanding what they submit.</strong> Sean McLellan&apos;s case for the <code>Assisted-by:</code> Git trailer states the reasoning plainly&#x2014;using <code>Co-authored-by:</code> claims shared authorship, and with it <em>accountability</em>. A tool can&apos;t hold up its end of that bargain.<sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup> The trailer itself is one lightweight implementation; the claim underneath it is what travels.</p>
<p>Accountability is what the trailer is <em>for</em>; <em>responsibility</em> is what the policies actually ask of you. Part of that is legal clarity&#x2014;the human is the sole <em>author</em> of the commit, whatever helped them write it. But what responsibility looks like in practice depends on the author&apos;s relationship to the project.</p>
<p>Two mechanisms tend to get bundled together here. <strong>Disclosure</strong> is a record-keeping rule&#x2014;the <code>Assisted-by:</code> trailer, the <a href="https://github.com/stdlib-js/stdlib/blob/fd17bfa9bc99c1abbd3d99e882cb18bddab42c08/.github/PULL_REQUEST_TEMPLATE.md?plain=1&amp;ref=blog.stdlib.io#L37-L55">AI-assistance section of our own PR template</a>&#x2014;and what it produces is provenance: <em>what helped write this</em>. Everyone takes part in that one. <strong>Gating</strong> is a permission rule: who may use these tools, on what, with how much latitude. What follows is an argument about the gate, not the disclosure.</p>
<p>A maintainer who merges a bad change is still there in three months when it breaks. They wrote the module it broke, or reviewed it, and they will be the one bisecting at midnight to find out why the build went red. Responsibility, for them, isn&apos;t a claim. It&apos;s a structural fact about where they&apos;re standing.</p>
<p>An infrequent contributor who submits a bad change usually isn&apos;t there. Not out of bad faith&#x2014;that&apos;s simply what infrequent means. Whatever <em>I take responsibility for this</em> means when they sign off on their PR, it can&apos;t mean quite the same thing as it does for a maintainer. The position it&apos;s said from is different.</p>
<p>So a policy that says <em>you&apos;re responsible for what you submit</em> is asking two structurally different things of two structurally different people, while looking like it asks one thing of everyone. That&apos;s roughly where our hypocrisy objection came from. It&apos;s also, it turns out, where the objection comes apart.</p>
<h2 id="the-word-for-it">The word for it</h2>
<p>There&apos;s a word for a rule that behaves this way, and I&apos;m going to use it even though it&apos;s unfamiliar, because the precise word does work the familiar ones don&apos;t.</p>
<p>A rule can be <strong>defeasible</strong>: correct as a default, and <em>properly overridden</em> when the situations it applies to genuinely differ. The everyday version is <em>the speed limit is 45, except for the ambulance.</em> The rule holds. The exception is principled. The exception doesn&apos;t retroactively invalidate the rule.<sup class="footnote-ref"><a href="#fn10" id="fnref10">[10]</a></sup></p>
<p>The open-source policy version goes something like this:</p>
<p>There&apos;s a na&#xEF;ve consistency heuristic: <em>don&apos;t require of others what you wouldn&apos;t do yourself</em>. It&apos;s correct for most governance choices. Don&apos;t require signed commits if you don&apos;t sign yours. Don&apos;t require test coverage your codebase doesn&apos;t have.</p>
<p>But it&apos;s <em>defeasible</em> where the situations genuinely differ, and AI-use policy is the clean case. A maintainer using AI owns the fallout, holds the project&apos;s mental model, and can recognize when the output is wrong. A first-time contributor using AI may be offloading understanding to the tool&#x2014;producing work they can&apos;t fully vouch for&#x2014;and has no accountability chain yet. Those are different situations. Different rules are warranted.</p>
<p>The distinction comes down to what&apos;s underneath the rule. <em>Because I own the fallout in a way you don&apos;t</em> is principled. <em>Because I said so</em> isn&apos;t. The trust ledger is what makes the difference legible, and it&apos;s why &quot;just be consistent&quot; is worse advice than it sounds.</p>
<p>The na&#xEF;ve-consistency rule is itself defeasible. That&apos;s the whole thing. It&apos;s a good default, it does honest work most of the time, and this is one of the situations where the exception is warranted rather than merely convenient.</p>
<p>Ghostty&apos;s <code>AI_POLICY.md</code> lays out the usual disclosure-and-human-in-the-loop rules for contributions, and then closes with this:<sup class="footnote-ref"><a href="#fn11" id="fnref11">[11]</a></sup></p>
<blockquote>
<p>These rules apply only to outside contributions to Ghostty.<br>
Maintainers are exempt from these rules and may use AI tools at their discretion; they&apos;ve proven themselves trustworthy to apply good judgment.</p>
</blockquote>
<p>Two sentences. The first says <em>this policy is for you, the contributor, not for me.</em> The second says <em>why.</em> And the why isn&apos;t brash authority&#x2014;it&apos;s a claim about accumulated context. <em>They&apos;ve proven themselves.</em> You can agree with it, or push back on it, or ask what the proving consisted of.</p>
<p>So: you (potential contributor) can weigh and evaluate the claim. Naming the asymmetry on the page&#x2014;rather than writing a symmetric-sounding rule and then quietly not applying it to yourself&#x2014;is the move. It&apos;s two sentences. It&apos;s been shipped, in public. Just like <a href="https://blog.stdlib.io/do-you-want-contributors/">a good <code>CONTRIBUTING.md</code></a>, the honest accounting is a kindness.</p>
<h2 id="youre-just-formalizing-hierarchy">&quot;You&apos;re just formalizing hierarchy&quot;</h2>
<p>There&apos;s a critique here I too feel the pull of, and it might be part of what keeps projects like ours from making the move. <em>You&apos;re building a hierarchy where maintainers get one rule and contributors get another.</em></p>
<p>The hierarchy is already there, and has been the whole time&#x2014;and it&apos;s not just maintainers vs. contributors, there are often tiers of trust (maintainers is just a useful shorthand). A maintainer with three years of context on a codebase reads a stranger&apos;s PR differently from how they read their own or one of a long-time contributor. The maintainer/reviewer knows what&apos;s load-bearing, what&apos;s under active refactor, which review objections are terminal versus fixable. None of that is malicious; most of it isn&apos;t even conscious. It&apos;s what accumulated context does. Call it a &quot;trust ledger&quot; (a term I&apos;ll return to in a subsequent post).</p>
<p>What a written policy does is convert an existing asymmetry from <strong>invisible-and-unchallengeable</strong> into <strong>visible-and-contestable</strong>. That&apos;s an accountability gain, not a hierarchy invention. Writing it down is what makes it something you can be held to.</p>
<p>If you&apos;ve been sitting on a policy because the <em>but-I-don&apos;t-hold-myself-to-this</em> objection kept stopping you: note it, acknowledge that it does ethical work worth respecting in most contexts, <em>and</em> it doesn&apos;t apply here in the way it feels like it does. The situations genuinely differ. Different rules are principled when the difference has a reason you can be held to.</p>
<p>I&apos;m not saying every project should ship one; whether it&apos;s right for a given project depends on more than fits in a piece this size. What I <em>am</em> saying is that this particular reason for stalling&#x2014;the hypocrisy-avoidance reason, the one that stopped us&#x2014;is dissolvable.</p>
<p>Take it, if it&apos;s useful. Ours has been open since December; I&apos;m hoping this is a step towards closing it out.</p>
<hr>
<p class="dev-theme-author-blurb">
    <em>Mara Averick is a developer advocate at <a href="https://quansight.com/?ref=blog.stdlib.io">Quansight</a> and contributor experience lead for <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a>.</em>
</p>
<hr>
<p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p>
<p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p>
<blockquote>
<p>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</p>
</blockquote>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>stdlib-js/stdlib issue <a href="https://github.com/stdlib-js/stdlib/issues/9347?ref=blog.stdlib.io">#9347</a>, &quot;[RFC]: Add guidance concerning AI usage&quot;&#x2014;proposing disclosure of AI assistance in pull requests and issues, excluding <code>good first issue</code> work from AI-assisted resolution (per the draft PR&apos;s rule 5: &quot;these issues are intended to help newcomers learn about the project and gain experience with the mechanics of contributing&quot;), and ruling out model output posted as comments on GitHub or Zulip. Opened December 24, 2025. <a href="#fnref1" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn2" class="footnote-item"><p>stdlib-js/stdlib pull request <a href="https://github.com/stdlib-js/stdlib/pull/9459?ref=blog.stdlib.io">#9459</a>&#x2014;the companion draft PR adding the policy text, opened December 31, 2025; still a draft as of this writing. <a href="#fnref2" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn3" class="footnote-item"><p>Philipp Burckhardt, <a href="https://blog.stdlib.io/reflection-on-the-metr-study-2025/">&quot;Using AI in the development of stdlib,&quot;</a> Numerical Bits, July 17, 2025&#x2014;a reflection on stdlib&apos;s participation in METR&apos;s <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/?ref=blog.stdlib.io">&quot;Impact of Early-2025 AI on Experienced Open-Source Developer Productivity&quot;</a> study, in which two stdlib core contributors worked randomized project issues under AI-allowed and AI-disallowed conditions&#x2014;a snapshot from early 2025; both the models and the surrounding tooling have changed considerably since. <a href="#fnref3" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn4" class="footnote-item"><p>Melissa Weber Mendon&#xE7;a, <a href="https://github.com/melissawm/open-source-ai-contribution-policies?ref=blog.stdlib.io"><code>open-source-ai-contribution-policies</code></a>&#x2014;a community-sourced catalog framed simply as &quot;a list of policies by different open source projects about how to engage with AI-generated contributions.&quot; Roughly 100 project rows as of August 2026, plus separate sections for ongoing discussions and adjacent references. <a href="#fnref4" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn5" class="footnote-item"><p>Kate Holterhoff, <a href="https://redmonk.com/kholterhoff/2026/02/26/generative-ai-policy-landscape-in-open-source/?ref=blog.stdlib.io">&quot;The Generative AI Policy Landscape in Open Source,&quot;</a> RedMonk, February 26, 2026 (with rolling edits through April 12, 2026). The dimensionalized cross-section&#x2014;stance, primary concern, disclosure requirement, adoption date&#x2014;of the same underlying corpus Melissa&apos;s catalog and CHAOSS&apos;s list track from different registers. Companion <a href="https://oss-ai-policies.netlify.app/?ref=blog.stdlib.io">visualization site</a>. <a href="#fnref5" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn6" class="footnote-item"><p>CHAOSS AI Alignment Working Group, <a href="https://github.com/chaoss/wg-ai-alignment/blob/main/moderation/README.md?ref=blog.stdlib.io">&quot;Awesome LLM Policy,&quot;</a> live PR-editable catalog with a nine-part taxonomy&#x2014;including <em>discussion</em> threads and <em>incident evidence</em> as first-class categories alongside finished policy artifacts. <a href="#fnref6" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn7" class="footnote-item"><p>The adjacent body of work is about as short as the list of trackers. Sviatoslav Sydorenko&apos;s <a href="https://gist.github.com/webknjaz/1819dd466cc908ff09e2ed4d934455eb?ref=blog.stdlib.io">EuroPython 2026 reference gist</a> collects the maintainer-side tooling and files both Holterhoff&apos;s RedMonk piece and the CHAOSS list under &quot;Surveys of the policy landscape&quot;; the three trackers each reference the other two. <a href="#fnref7" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn8" class="footnote-item"><p>James Fredley, <a href="https://allthingsopen.org/articles/open-source-ai-contributions-assisted-by-git-trailer-standard?ref=blog.stdlib.io">&quot;Assisted-by: How open source projects are drawing the line on AI contributions,&quot;</a> All Things Open, May 11, 2026. A tier-by-tier read from the primary documents&#x2014;QEMU, Gentoo, and NetBSD at the total-ban end; LLVM, Fedora, the Linux Kernel, Apache, OpenInfra, OpenTelemetry, and Rocky Linux across the permissive-with-disclosure middle&#x2014;arguing that <code>Assisted-by:</code> is settling in as the de facto convention over <code>Co-authored-by:</code>, which &quot;implies legal personhood.&quot; Fredley is chair of the Apache Grails PMC. <a href="#fnref8" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn9" class="footnote-item"><p>Sean McLellan, <a href="https://www.baristalabs.io/blog/ai-assisted-commits-need-provenance-trailer?ref=blog.stdlib.io">&quot;Assisted-by git trailer: provenance for AI-assisted commits,&quot;</a> Barista Labs, June 20, 2026. Key line: &quot;Co-authorship says this entity shares authorship and accountability.&quot; Pulled into stdlib&apos;s own trailer discussion by Athan Reines&apos; (<a href="https://github.com/stdlib-js/stdlib/issues/9347?ref=blog.stdlib.io#issuecomment-5052552276">comment</a> on issue <a href="https://github.com/stdlib-js/stdlib/issues/9347?ref=blog.stdlib.io">#9347</a>)&#x2014;not necessarily the line&apos;s original point of entry into OSS AI-policy discourse, just where this piece&apos;s thread of it traces back to. <a href="#fnref9" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn10" class="footnote-item"><p>The term has a longer life outside software. H. L. A. Hart, <a href="http://www.jstor.org/stable/4544455?ref=blog.stdlib.io">&quot;The Ascription of Responsibility and Rights,&quot;</a> <em>Proceedings of the Aristotelian Society, New Series</em> 49 (1948&#x2013;1949): 171&#x2013;194, is the canonical statement of the legal version&#x2014;rules that hold unless a specific exception overrides them. John L. Pollock, <a href="https://doi.org/10.1207/s15516709cog1104_4?ref=blog.stdlib.io">&quot;Defeasible Reasoning,&quot;</a> <em>Cognitive Science</em> 11, no. 4 (1987): 481&#x2013;518, formalizes the everyday version: how people reason with rough-and-ready rules that new information can <em>defeat</em>, and what it takes for an override to count. <a href="#fnref10" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn11" class="footnote-item"><p>Ghostty, <a href="https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md?ref=blog.stdlib.io"><code>AI_POLICY.md</code></a> (fetched 2026-08-03). Iterated in public via PR <a href="https://github.com/ghostty-org/ghostty/pull/8289?ref=blog.stdlib.io">#8289</a> (initial disclosure rules, August 2025) and PR <a href="https://github.com/ghostty-org/ghostty/pull/10412?ref=blog.stdlib.io">#10412</a> (hardened into the standalone policy, January 2026). <a href="#fnref11" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Why another plotting library?]]></title><description><![CDATA[JavaScript has no shortage of plotting libraries. But scientific computing needs more than a way to render charts, so we're building a plotting system designed around the entire workflow.]]></description><link>https://blog.stdlib.io/why-another-plotting-library/</link><guid isPermaLink="false">6a77a70e81c4de9ae6e8753d</guid><category><![CDATA[Engineering]]></category><dc:creator><![CDATA[Athan Reines]]></dc:creator><pubDate>Sat, 08 Aug 2026 22:20:41 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/08/gen_splash-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/08/gen_splash-2.png" alt="Why another plotting library?"><p>JavaScript does not suffer from a shortage of ways to draw a chart. There are mature libraries for quick statistical graphics, dashboards, bespoke data-driven documents, publication-quality figures, and nearly every use case in between. Some are small and focused. Others are entire ecosystems in their own right.</p><p>So, naturally, stdlib is building another one.</p><p>At first glance, this may look like a textbook case of not-invented-here. It is not. We are not building a plotting library because we think the existing libraries are bad. Quite the opposite: JavaScript has some of the best visualization tooling of any programming ecosystem. We are building one because stdlib is trying to solve a <em>different</em> problem.</p><p>The gap we care about is not at the level of pixels. Current JavaScript charting libraries can draw lines, symbols, axes, legends, and tooltips just fine. The gap is at the level of workflow: how plotting fits into numerical computation across the browser, the REPL, the command line, on the server, and in desktop windows.</p><p>That is the problem we have not seen addressed as one coherent system.</p><h2 id="tldr">TL;DR</h2><p>We are not building another rendering engine.</p><p>We are building a plotting layer for scientific JavaScript: one which understands n-dimensional arrays (a.k.a., <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/ctor?ref=blog.stdlib.io"><code>ndarrays</code></a>), works naturally in the Node.js REPL, can render to an Electron-powered desktop window, participates in command-line workflows, can be embedded in a browser, exposes a programmatic event model, and provides a path from exploratory analysis to publication-quality graphics.</p><p>For rendering and interaction, we are building on <a href="https://vega.github.io/?ref=blog.stdlib.io">Vega</a>, a declarative visualization grammar and runtime which produces canvas and SVG output in the browser, and supports static rendering on the server. Vega gives us a robust target specification and rendering backend. stdlib provides the scientific data model, ergonomic plotting APIs, runtime integrations, object model, viewers, editing tools, documentation, testing, and long-term compatibility layer around it.</p><p>Put another way: Vega handles the pixels. We are building the workflow.</p><h2 id="start-where-the-computation-happens">Start where the computation happens</h2><p>Most JavaScript visualization libraries treat the browser as the center of the universe. That makes sense. JavaScript was born in the browser, and the browser provides a rich environment for interaction, layout, animation, and graphical output. For many applications, targeting a DOM element on a web page is the right abstraction.</p><p>But stdlib does not live only in the browser.</p><p>It also lives in Node.js scripts, REPL sessions, command-line programs, batch jobs, data pipelines, web services, and other server-side environments. If plotting is going to be a first-class part of scientific computing in JavaScript, it needs to feel at home in all of those places.</p><p>When I am exploring a dataset, I do not want to create a browser application just to see whether two variables are correlated. I do not want to scaffold a project, write HTML, start a development server, move my data across an application boundary, and attach a chart to a DOM node. I want to start the stdlib <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/repl?ref=blog.stdlib.io">REPL</a>, load my data, create a plot, and keep working.</p><p>That should not be a radical request.</p><p>The plotting work currently underway in stdlib deliberately separates a chart from how that chart is viewed. The same chart can target <code>stdout</code>, a browser, or an Electron-powered desktop window. A browser remains a first-class destination, but it is not assumed to be the only destination.</p><figure class="kg-card kg-video-card kg-width-wide kg-card-hascaption" data-kg-thumbnail="https://blog.stdlib.io/content/media/2026/08/update_plot_via_repl_2x_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://blog.stdlib.io/content/media/2026/08/update_plot_via_repl_2x.mp4" poster="https://img.spacergif.org/v1/3840x2160/0a/spacer.png" width="3840" height="2160" loop autoplay muted playsinline preload="metadata" style="background: transparent url(&apos;https://blog.stdlib.io/content/media/2026/08/update_plot_via_repl_2x_thumb.jpg&apos;) 50% 50% / cover no-repeat;"></video>
                <div class="kg-video-overlay">
                    <button class="kg-video-large-play-icon" aria-label="Play video">
                        <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/>
                        </svg>
                    </button>
                </div>
                <div class="kg-video-player-container kg-video-hide">
                    <div class="kg-video-player">
                        <button class="kg-video-play-icon" aria-label="Play video">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/>
                            </svg>
                        </button>
                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/>
                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/>
                            </svg>
                        </button>
                        <span class="kg-video-current-time">0:00</span>
                        <div class="kg-video-time">
                            /<span class="kg-video-duration">0:57</span>
                        </div>
                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1&#xD7;</button>
                        <button class="kg-video-unmute-icon" aria-label="Unmute">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/>
                            </svg>
                        </button>
                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/>
                            </svg>
                        </button>
                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
                    </div>
                </div>
            </div>
            <figcaption><p dir="ltr"><span style="white-space: pre-wrap;">Programmatic environments such as REPLs and interactive notebooks are fundamental to exploratory data analysis. Filtering, reshaping, visualizing, and interrogating data is inherently iterative, and requiring a separate browser application introduces unnecessary friction into that loop. Here, an ndarray created in the stdlib REPL is passed directly to a chart constructor and rendered in a browser, after which programmatic changes to the chart are propagated automatically to the rendered view.</span></p></figcaption>
        </figure><p>This matters for exploratory data analysis. Plotting is not merely a final presentation step. It is part of the feedback loop through which we inspect data, question assumptions, identify structure, discover errors, and decide what to compute next. A plotting library for scientific computing should begin where the computation happens, not require users to move the computation somewhere else.</p><h2 id="numerical-data-is-not-always-a-json-table">Numerical data is not always a JSON table</h2><p>A great deal of JavaScript visualization is organized around arrays of objects (often referred to as <a href="https://vita.had.co.nz/papers/tidy-data.html?ref=blog.stdlib.io">&quot;tidy datasets&quot;</a>; e.g., see <a href="https://vega.github.io/vega/docs/data/?ref=blog.stdlib.io">Vega</a> and <a href="https://observablehq.com/plot/features/marks?ref=blog.stdlib.io#marks-have-tidy-data">Observable Plot</a>):</p><pre><code class="language-javascript">[
    { &apos;x&apos;: 1.0, &apos;y&apos;: 3.2 },
    { &apos;x&apos;: 2.0, &apos;y&apos;: 4.8 },
    { &apos;x&apos;: 3.0, &apos;y&apos;: 4.1 }
]
</code></pre><p>That is a perfectly reasonable interchange format centered on <a href="https://en.wikipedia.org/wiki/JSON?ref=blog.stdlib.io">JSON</a>. It is readable, flexible, and maps naturally to rows and fields. It is not, however, necessarily the data model used by a numerical program.</p><p>Scientific code routinely works with typed arrays, multi-dimensional arrays, strided views, non-contiguous memory layouts, stacks of matrices, and arrays with explicit shape and data type information. Those objects are not incidental implementation details. They are fundamental abstractions around which numerical software is built.</p><p>In stdlib, we want users to be able to provide the same <code>ndarray</code> objects they use for statistics, linear algebra, simulation, and signal processing directly to plotting APIs. Users should not need to manually flatten, reshape, transpose, copy, or serialize their data just to look at it.</p><p>Our work-in-progress line-chart implementation already accepts <code>ndarray</code>-like inputs, determines how to organize those inputs as chart data, and lowers the result into Vega datasets, scales, axes, and marks.</p><pre><code class="language-javascript">const uniform = require( &apos;@stdlib/random/uniform&apos; );
const Float64Vector = require( &apos;@stdlib/ndarray/vector/float64&apos; );
const LineChart = require( &apos;./../lib&apos; );

// Define minimum lower and upper bounds for uniformly distributed random numbers:
const a = new Float64Vector( [ 10, 20, 30, 40, 50 ] );
const b = new Float64Vector( [ 20, 30, 40, 50, 60 ] );

// Generate 5 datasets containing 100 rows of data:
const y = uniform( [ 100, 5 ], a, b );

// Create a new chart instance:
const chart = new LineChart( y );
</code></pre><p>This is not the sort of feature which produces a flashy landing-page demo. But it is foundational.</p><p>A plotting library within stdlib should understand the data structures produced by the rest of stdlib. Anything less would make plotting feel like an attached application rather than an integrated part of the numerical computing environment.</p><h2 id="a-plot-should-be-a-live-computational-object">A plot should be a live computational object</h2><p>A plot is often treated as a terminal artifact: provide some data and options, create an SVG or canvas element, and move on. That model is useful, but incomplete.</p><p>Plots change. Data arrives. Parameters are updated. Axes are rescaled. Themes are switched. A server may need to notify a connected client. A host application may need to export an image after a computation finishes. A stream may need to trigger an update without any DOM event occurring.</p><p><a href="https://vega.github.io/vega/docs/signals/?ref=blog.stdlib.io">Vega signals</a> provide an excellent reactive model within the visualization runtime. Signal values can respond to input events, external API calls, and upstream changes, with updated values propagating through the visualization dataflow. But signals inside a visualization runtime are not a replacement for a general-purpose event model across a JavaScript object graph.</p><p>In our current work, stdlib plotting objects use event emitters throughout the programmatic API. Changes to child objects propagate upward, allowing a chart, server, viewer, logger, or another consumer to respond. A change can result in a visual update, but it could just as readily result in writing a file, emitting a message over a socket, recording an audit log, or initiating some other non-DOM action. This is particularly important on the server, where there may be no user-interface element to bind and no mouse or keyboard event to observe.</p><p>It is also why we are investing in debug logging throughout the plotting stack. Once a visualization becomes reactive, understanding what changed, where that change originated, and why a render occurred becomes essential. Plotting should not be a black box which mysteriously redraws itself. Failure should be easy to diagnose.</p><p>In other words, we are treating a plot as a live computational object, not just a picture.</p><h2 id="code-and-gui-should-meet-in-the-middle">Code and GUI should meet in the middle</h2><p>There is a longstanding tension in scientific plotting between code and graphical editing. Code is reproducible. It can be reviewed, versioned, rerun, tested, and applied consistently across many figures. A graphical interface, however, can be much more efficient for the final stages of figure creation: adjusting padding, changing font sizes, refining tick marks, moving a legend, modifying line styles, and making the dozens of small visual decisions which turn a serviceable plot into a publication-quality graphic.</p><p>Most tools force users to choose. Either every visual detail must be expressed in code, even when direct manipulation would be faster, or a figure is edited in a graphical application and the relationship between the resulting artifact and the code which produced it is severed.</p><p>We want both.</p><p>The current in-progress plotting <a href="https://github.com/stdlib-js/stdlib/pull/7715?ref=blog.stdlib.io">work</a> contains an early graphical editor which reads from a visualization schema, exposes controls for chart properties, and posts changes back to a server-side plot. The underlying schema remains the source of truth. Programmatic changes can update the editor, and editor changes can update the programmatic object.</p><figure class="kg-card kg-video-card kg-width-wide kg-card-hascaption" data-kg-thumbnail="https://blog.stdlib.io/content/media/2026/08/plot_gui_2x_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://blog.stdlib.io/content/media/2026/08/plot_gui_2x.mp4" poster="https://img.spacergif.org/v1/3840x2160/0a/spacer.png" width="3840" height="2160" loop autoplay muted playsinline preload="metadata" style="background: transparent url(&apos;https://blog.stdlib.io/content/media/2026/08/plot_gui_2x_thumb.jpg&apos;) 50% 50% / cover no-repeat;"></video>
                <div class="kg-video-overlay">
                    <button class="kg-video-large-play-icon" aria-label="Play video">
                        <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/>
                        </svg>
                    </button>
                </div>
                <div class="kg-video-player-container kg-video-hide">
                    <div class="kg-video-player">
                        <button class="kg-video-play-icon" aria-label="Play video">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/>
                            </svg>
                        </button>
                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/>
                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/>
                            </svg>
                        </button>
                        <span class="kg-video-current-time">0:00</span>
                        <div class="kg-video-time">
                            /<span class="kg-video-duration">0:36</span>
                        </div>
                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1&#xD7;</button>
                        <button class="kg-video-unmute-icon" aria-label="Unmute">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/>
                            </svg>
                        </button>
                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
                            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/>
                            </svg>
                        </button>
                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
                    </div>
                </div>
            </div>
            <figcaption><p dir="ltr"><span style="white-space: pre-wrap;">A graphical user interface (GUI) allows chart properties to be edited directly while keeping the underlying chart object synchronized with the rendered view. Changes made in the GUI are reflected in the chart instance running in the REPL, while programmatic changes made in the REPL are reflected in the browser. This two-way synchronization makes it possible to combine the reproducibility of a programmatic workflow with the immediacy of direct manipulation when iterating on a visualization.</span></p></figcaption>
        </figure><p>This work is still early, but the direction is important. The goal is not to replace code with a GUI. It is to make the GUI another frontend to the same underlying representation.</p><h2 id="knowing-when-to-stop-building-everything-ourselves">Knowing when to stop building everything ourselves</h2><p>At this point, an obvious question arises. If we are building so much custom plotting infrastructure, why build on Vega at all? Why not implement the renderer ourselves?</p><p>We tried.</p><p>stdlib has a strong bias toward building foundational infrastructure in-house. That tendency has served us well. It gives us control over API design, behavior, performance, portability, testing, documentation, and release cadence.</p><p>Our original plotting implementation followed that instinct. We built SVG components, virtual-DOM infrastructure, scales, axes, marks, layout logic, and rendering machinery. It worked. It also made increasingly clear just how much work remained.</p><p>A serious visualization renderer needs to handle scenegraphs, data joins, text measurement, clipping, layout, rendering order, incremental updates, animation, browser differences, event handling, image export, accessibility, canvas, SVG, server-side rendering, and a seemingly endless collection of edge cases. We could keep investing in all of that. But doing so would mean spending an enormous amount of time reproducing infrastructure which already exists and is maintained by people who have devoted years to solving those exact problems.</p><p>At some point, persistence becomes stubbornness. So we folded that hand.</p><p>The <a href="https://github.com/stdlib-js/stdlib/pull/7715?ref=blog.stdlib.io">pull request</a> containing the current work explicitly removes the previous virtual-DOM plotting implementation and replaces it with packages for constructing and generating Vega specifications. That does not mean the previous work was wasted. Quite the opposite. It taught us where the correct abstraction boundary should be.</p><p>We do not need to own every pixel in order to own the user experience. Rendering is not where stdlib can add the most value. Integrating plotting into scientific JavaScript is.</p><h2 id="why-vega">Why Vega?</h2><p>Vega is described as a visualization grammar. Rather than directly issuing imperative drawing commands, a Vega visualization is described using a <a href="https://vega.github.io/vega/docs/specification/?ref=blog.stdlib.io">JSON specification</a> containing data, scales, axes, legends, marks, signals, and other components. The specification is then parsed into a reactive dataflow and rendered by the Vega runtime.</p><p>That distinction makes Vega a particularly good fit for what we are building.</p><h3 id="a-portable-intermediate-representation">A portable intermediate representation</h3><p>We treat a Vega specification as an intermediate representation, which is one of the stated goals of Vega: namely, to provide a <a href="https://vega.github.io/vega/about/vega-and-d3/?ref=blog.stdlib.io">&quot;target language&quot;</a> in which computer programs can dynamically generate visualizations.</p><p>Conceptually, the architecture looks something like this:</p><pre><code class="language-text"> high-level chart   future plotting
    constructors       DSLs
            \       /
             \     /
        low-level builders     GUI editor
                 \               /
                  \             /
                Vega specification
                         |
                    Vega runtime
                         |
            SVG / Canvas / other renderers
</code></pre><p>A high-level line-chart constructor does not need to know how to create SVG paths, draw onto a canvas context, or generate shaders. It needs to know how to translate the user&apos;s intent and data into a valid visualization specification. Similarly, a graphical editor does not need its own rendering engine. It can modify the same specification generated by a programmatic API.</p><p>This is not an untested architectural model. <a href="https://vega.github.io/vega-lite/?ref=blog.stdlib.io">Vega-Lite</a> is itself a higher-level grammar which compiles to Vega. <a href="https://github.com/vega/lyra?ref=blog.stdlib.io">Lyra</a> was an initial attempt at a graphical environment for custom visualization design without writing any code. We are applying a similar separation, but building a different frontend, one which is shaped around JavaScript numerical computing, stdlib conventions, and direct integration with stdlib data structures, such as <code>ndarrays</code>.</p><p>Vega specifications also give us portable artifacts which can be inspected, serialized, stored, shared, transformed, and handed to other tools. Because Vega and Vega-Lite sit underneath tools in other ecosystems, including <a href="https://altair-viz.github.io/?ref=blog.stdlib.io">Altair</a> and <a href="https://vegafusion.io/?ref=blog.stdlib.io">VegaFusion</a> in Python, the specification provides a natural bridge beyond JavaScript as well.</p><p>The schema becomes a boundary rather than a burden.</p><h3 id="multiple-rendering-environments">Multiple rendering environments</h3><p>Vega supports canvas and SVG rendering in the browser and static SVG and PNG export on the server. Server-side SVG generation does not require constructing a server-side DOM. Vega provides multi-view layout machinery, configuration-based theming, and explicit accessibility properties for SVG output. Third-party work has additionally demonstrated a <a href="https://github.com/vega/vega-webgl-renderer?ref=blog.stdlib.io">WebGL renderer</a> for the Vega scenegraph.</p><p>Those capabilities would each represent substantial projects in their own right. By building on Vega, we inherit a rendering foundation which already spans the environments stdlib cares about. We can then spend our time on the problems which are specific to scientific computing: data adapters, chart semantics, numerical types, server integration, REPL workflows, command-line composition, and user-facing APIs.</p><h3 id="reactive-behavior-on-the-client">Reactive behavior on the client</h3><p>Vega&apos;s signals and reactive dataflow allow many updates to be resolved directly within the client-side runtime. Not every change should require sending an entirely new specification from a server. A line color, tick size, font weight, or opacity can often be updated without rebuilding the world.</p><p>The current in-progress stdlib view implementation already distinguishes between properties which can be updated dynamically and structural changes which require the specification to be re-parsed. This gives us a useful division of labor. stdlib can own the server-side object model and change propagation, while Vega can handle reactive visual updates close to where rendering occurs and facilitate a more responsive and snappier user experience.</p><h3 id="an-ecosystem-rather-than-an-island">An ecosystem rather than an island</h3><p>Depending on a rendering backend is not a decision we take lightly. Visualization libraries are expensive dependencies. They have large surface areas, and choosing one means placing a certain amount of trust in its architecture, maintainers, and continued development. Vega has continued to evolve, remains actively maintained, and supports a broader ecosystem including Vega-Lite, Altair, VegaFusion, <a href="https://github.com/vega/vega-embed/?ref=blog.stdlib.io">Vega-Embed</a>, <a href="https://github.com/vega/vega-themes?ref=blog.stdlib.io">Vega Themes</a>, and the <a href="https://github.com/vega/editor?ref=blog.stdlib.io">Vega Editor</a>.</p><p>That matters.</p><p>We are not tying stdlib to an isolated renderer which only we depend upon. We are aligning with a specification and runtime already shared across languages, applications, and communities.</p><h2 id="vega-is-the-backend-not-the-user-facing-api">Vega is the backend, not the user-facing API</h2><p>One might reasonably ask: why not simply tell users to write Vega specifications directly? Our answer is that, while powerful, Vega is also low-level.</p><p>Creating even a conventional chart can require thinking about datasets, scales, domains, ranges, axes, marks, encoding sets, value references, signals, and layout, and then trying to encode that in JSON. That level of control is invaluable when building novel visualizations. It is unnecessary ceremony when someone simply wants to plot <code>x</code> against <code>y</code>. A scientist should not need to learn a visualization grammar before inspecting an array.</p><p>stdlib&apos;s role is to provide ergonomic plotting APIs inspired by established numerical environments such as MATLAB and <a href="https://matplotlib.org/?ref=blog.stdlib.io">matplotlib</a>, while retaining the ability to reach for the full expressive power of Vega when needed. At the highest level, that may mean static chart constructors which make common plots easy. At a lower level, it means programmatic objects corresponding to Vega concepts such as data sources, scales, axes, marks, and encoding sets. Those objects provide validation, defaults, property accessors, change events, debug logs, and predictable serialization. And, at the bottom, the generated Vega specification remains available as an escape hatch and interoperability format.</p><p>The work-in-progress implementation already reflects this layering: high-level quantitative and line-chart objects are composed from lower-level Vega dataset, scale, axis, mark, encoding, and value objects before serializing to a standard specification.</p><p>This is not intended to be a thin wrapper which renames a few Vega properties. What we are building is a frontend and integration layer.</p><h2 id="the-value-is-in-the-continuity">The value is in the continuity</h2><p>To be clear, we are not claiming that every individual feature we want is unprecedented. That would be both false and unhelpful.</p><p>Vega already renders on the server. Other libraries can be made to work with Node.js. Command-line visualization tools exist. Graphical chart editors exist. Some libraries accept typed arrays or can be used inside Electron.</p><p>The individual pieces are out there. What we have not found is a coherent system which brings those pieces together around scientific computing in JavaScript.</p><p>Consider the workflow we are working toward:</p><p>Load an <code>ndarray</code>. Create a chart without manually reshaping the data. Open the chart in a desktop window directly from the REPL. Update a property and see the view react. Listen for changes from another server-side object. Inspect debug logs to understand why the plot updated. Fine-tune the figure in a graphical editor. Serialize the same underlying specification to stdout. Embed the same visualization in a browser application. Hand the specification to a tool in another ecosystem.</p><p>No single step is the point. The continuity is.</p><h2 id="building-it-the-stdlib-way">Building it the stdlib way</h2><p>The plotting work is also being built according to the same <a href="https://blog.stdlib.io/zen-of-stdlib/">principles</a> which guide the rest of stdlib. Low-level components are modular and independently usable. Higher-level behavior is composed from those components. Complexity is pushed upward into APIs which can provide convenience without compromising the predictability of the foundations underneath.</p><p>Yes, this results in more packages than placing everything inside a single <code>plot</code> function. It also gives each concept a clear boundary. Components can be tested in isolation, documented independently, benchmarked where appropriate, reused by other packages, and replaced without rewriting the entire plotting system.</p><p>Just as importantly, stdlib owns the user-facing compatibility boundary.</p><p>Vega may evolve. Renderers may change. New specification versions may be released. By placing stdlib APIs in front of that machinery, we can absorb upstream changes, maintain consistent conventions across the rest of the project, and release plotting functionality according to the needs of stdlib users.</p><p>Depending on Vega does not mean surrendering control. It means focusing our control at the layer where we can add the most value.</p><h2 id="where-things-stand">Where things stand</h2><p>This is not a launch announcement. The plotting work currently lives in a long-running draft <a href="https://github.com/stdlib-js/stdlib/pull/7715?ref=blog.stdlib.io">pull request</a>, and it is not ready for general use. API names may change. Package boundaries may move. Some features are incomplete, and many details remain to be worked out. But we have made significant progress.</p><p>The branch now contains a programmatic Vega object model, data conversion utilities, scales, axes, marks, encoding objects, high-level chart constructors, direct <code>ndarray</code> support, multiple view targets, server-side change propagation, and an early graphical editor. Enough of the architecture is now working that the direction is no longer hypothetical.</p><p>We are sharing the rationale before the software is finished because we think the motivation matters. From the outside, another plotting library can look like duplication for duplication&apos;s sake. From inside stdlib, it is an important missing piece in our effort to provide a comprehensive environment for scientific computing and data analysis in JavaScript.</p><p>We welcome initial feedback, especially from those whose workflows move between the REPL, scripts, servers, browsers, command-line tools, and publication systems. Those are precisely the boundaries we want to make disappear.</p><h2 id="closing">Closing</h2><p>JavaScript does not need another plotting library in the abstract. stdlib does need a plotting system designed around scientific JavaScript.</p><p>A scientific computing environment is incomplete if it can perform a computation but cannot help you inspect, explore, understand, and communicate the result. Visualization is not an accessory to data analysis. It is part of the process by which analysis happens.</p><p>We are not trying to replace every existing visualization library, nor are we trying to win a chart-library arms race. We are trying to make scientific computing in JavaScript feel whole.</p><p>That means starting where the data lives. It means supporting the runtime the user is already working in. It means understanding numerical data structures. It means treating plots as live computational objects. And it means knowing when to build our own infrastructure and when to rely on excellent work already available in the broader ecosystem.</p><p>Yes, data visualization in JavaScript is a rather frothy and noisy space.</p><p>And yet, here we are.</p><p>That is why we are building another plotting library.</p><hr><p><em>Athan Reines is a software engineer at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and core developer of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote>]]></content:encoded></item><item><title><![CDATA[The Codebase Is the Prompt]]></title><description><![CDATA[Every inconsistency in your repository is a bug in the specification you are handing your AI agent.]]></description><link>https://blog.stdlib.io/the-codebase-is-the-prompt/</link><guid isPermaLink="false">6a75c9d181c4de9ae6e8751f</guid><category><![CDATA[Engineering]]></category><dc:creator><![CDATA[Karan Anand]]></dc:creator><pubDate>Fri, 07 Aug 2026 12:17:50 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/08/gen_splash-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/08/gen_splash-1.png" alt="The Codebase Is the Prompt"><p>For most of the last eight months, my prompts have been the same sentence with two package names swapped.</p><pre><code class="language-text">Ok, considering `blas/ext/base/gxmy` as the closest reference
implementation, we need to refactor everything in
`blas/ext/base/gxdy`.

The difference is mostly implementation, and some other things
you will figure out when comparing.

But as far as structure goes, `blas/ext/base/gxmy` is the way
to go.
</code></pre><p>I have typed some version of that dozens of times, mostly inside <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/base?ref=blog.stdlib.io"><code>blas/ext/base</code></a>. The package names can look like line noise if you don&apos;t know the naming scheme. The leading letter often identifies the data type, while the rest describes the operation. You don&apos;t need to remember the details. The important part is that related packages follow recognizable patterns.</p><p>It&apos;s not a clever prompt. There&apos;s no elaborate role, long checklist, or prompting trick. It points at a package that already exists and says: follow that pattern, with these differences.</p><p>And it works surprisingly often.</p><p>It took me a while to understand why. The answer turned out to be more interesting than the prompt itself. It works because of how stdlib is built.</p><h2 id="thousands-of-siblings">Thousands of siblings</h2><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is a standard library for JavaScript and Node.js focused on numerical and scientific computing. It is assembled from thousands of small packages under <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib?ref=blog.stdlib.io"><code>lib/node_modules/@stdlib</code></a>, each of which can be installed independently. They are not thousands of unique snowflakes. They are variations on a much smaller number of shapes.</p><p>A strided BLAS routine looks like other strided BLAS routines. A LAPACK auxiliary routine follows the same general package structure as its neighbors, with similar files, section comments, documentation, tests, and naming conventions.</p><p>The <a href="https://blog.stdlib.io/zen-of-stdlib/">Zen of stdlib</a> puts it plainly:</p><blockquote>Value consistency above all else.</blockquote><p>That principle was written for people. A contributor who implements one package can recognize the shape of many others. Consistency becomes a teaching tool and a promise that the next package won&apos;t require starting from scratch. Nobody wrote that principle with language models in mind. But a codebase where packages consistently resemble their neighbors is also one of the best things you can give an AI agent.</p><p>When I point an LLM at <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/base/gxmy?ref=blog.stdlib.io"><code>blas/ext/base/gxmy</code></a> and ask for <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/base/gxdy?ref=blog.stdlib.io"><code>blas/ext/base/gxdy</code></a>, I am not asking the model to invent a package. I am asking it to compare two related operations and apply an existing pattern. The specification is not in a document. It is in the sibling package, sitting on disk, already reviewed, already merged, and already known to work.</p><p>The codebase is the prompt.</p><h2 id="a-messy-codebase-is-a-messy-prompt">A messy codebase is a messy prompt</h2><p>This is where the idea becomes uncomfortable. If precedent is your specification, every inconsistency in the repository becomes a bug in that specification. It&apos;s not only a cosmetic issue. A stale package using an old benchmark style is also a wrong answer waiting to be copied.</p><p>One of the other stdlib maintainers put this to me recently, and it changed how I thought about the problem. When a convention changes, you have two options:</p><ul><li>You can add another instruction telling the model to remember the exception; or</li><li>You can update the old packages, so the exception no longer exists.</li></ul><p>The second option is better when it is practical. Telling the model to remember is only a patch. It asks the model to carry an inconsistency and to keep track of which version is current. Fixing the codebase removes that ambiguity. The model can simply look around.</p><p>The same is true for people. Every &quot;ignore that file, it uses the old approach&quot; adds a small cost for every future contributor. We have always known this. AI agents only make the cost appear faster because they will find the old example and treat it as evidence.</p><p>I saw this during a <a href="https://github.com/stdlib-js/stdlib/issues/8647?ref=blog.stdlib.io">recent modernization effort</a>. Benchmark names used to be built by using string concatenation, and we have since migrated them to use string interpolation with <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/string/format?ref=blog.stdlib.io"><code>format()</code></a>, a pure JavaScript implementation of an API similar to C&apos;s <code>printf</code>. While that migration was in process, the tree had a mixture of both conventions. An agent adding benchmarks to a new package copied whichever style its nearest neighbor happened to use, and it was right to. Nothing in the old file says it&apos;s the old way.</p><p>Do not put off to tomorrow what you can fix today, because tomorrow an agent may read every version and assume they are all equally valid.</p><p>After stdlib participated in the <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/?ref=blog.stdlib.io">METR study</a>, which reported that experienced developers were 19 percent slower on tasks where they could use AI, Philipp Burckhardt wrote a <a href="https://blog.stdlib.io/reflection-on-the-metr-study-2025/">reflection</a> identifying two sources of friction: gaps in project conventions, and the blank slate from which an agent begins each session.</p><p>I think that diagnosis is right. An agent may not reliably remember an instruction from a previous session, but it can inspect the code in front of it. Consistency makes the right convention visible wherever the agent happens to begin.</p><p>This is why much of my work this year has looked boring from the outside. Updating benchmark names. Modernizing tests. Cleaning up old conventions across <a href="https://github.com/stdlib-js/stdlib/pulls?q=sort%3Aupdated-desc+is%3Apr+author%3Aanandkaranubc+is%3Amerged&amp;ref=blog.stdlib.io">hundreds of pull requests</a>. I used to think of that work mainly as maintenance. I now also think of it as improving the examples that every future contributor, human or otherwise, will learn from.</p><h2 id="what-isnt-in-the-package">What isn&apos;t in the package</h2><p>Precedent is powerful, but it has a limit. Code shows you the <em>what</em>. It rarely shows you the <em>why</em>, and it doesn&apos;t always show you what to verify. A model can produce a correct implementation and still have no idea which checks to run before opening a pull request.</p><p>But that knowledge isn&apos;t only in people&apos;s heads. Much of it is already written down in the repository, just not inside the package you happen to be editing.</p><p>stdlib installs a <a href="https://github.com/stdlib-js/stdlib/blob/develop/tools/git/hooks/pre-commit?ref=blog.stdlib.io">pre-commit hook</a> that runs more than a dozen checks before a commit is allowed. It validates formatting, lints JavaScript separately for source, tests, examples, and benchmarks, checks the package manifest, lints Markdown and TypeScript declarations, and verifies license headers.</p><p>At the time of this post, there are <a href="https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/_tools/eslint/rules?ref=blog.stdlib.io">126 custom lint rules</a> written for this project alone, covering conventions a general linter has no reason to know: how a JSDoc block should be shaped, how doctest output should match, how a namespace should export its packages. There are <a href="https://github.com/stdlib-js/stdlib/tree/develop/docs/style-guides?ref=blog.stdlib.io">style guides</a> for every language in the tree, and a <a href="https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md?ref=blog.stdlib.io">contributing guide</a> describing what a reviewable pull request looks like.</p><p>None of that sits inside the package. All of it is machine readable.</p><p>That distinction matters more than I expected. An agent that doesn&apos;t know that these exist will guess, and its guesses will look plausible enough to survive a quick review. An agent that runs the hook is told exactly what is wrong, in the project&apos;s own words, without anyone writing a prompt about it.</p><p>So the most useful thing you can do for an agent is not to describe your conventions. It is to make them executable. A convention that lives in a reviewer&apos;s memory has to be repeated every time it&apos;s broken. A convention that lives in a lint rule enforces itself, for people and machines alike.</p><p>What tooling <em>cannot</em> decide is which existing package to imitate in the first place. Choosing the right reference is the one piece of guidance I had to write down for the model myself.</p><h2 id="finding-the-right-sibling">Finding the right sibling</h2><p>The most useful thing I learned while writing that guidance is that the valuable part is not another list of style rules. It is teaching the model how to find the right precedent.</p><p>For a new package, the guidance is a simple ladder:</p><ol><li>Look for the same operation at a different precision.</li><li>If that does not exist, find a routine with the same package shape and the same precision.</li><li>Otherwise, find the closest operation in the same family.</li></ol><p>Then, before editing anything, state the chosen reference and explain why it was selected.</p><p>That is the core of my repeated prompt, generalized. Instead of requiring me to know that <code>blas/ext/base/gxmy</code> is the right package to follow, the model has a process for finding the right package itself.</p><p>The final instruction matters more than it may appear. Asking the model to state its reference before writing code gives me a cheap place to stop it. If it chooses the wrong sibling, I find out in one sentence rather than after reviewing a four-hundred-line diff. Many of the poor outputs I have received began with the wrong reference. That mistake was visible before any code needed to be written.</p><h2 id="what-i-would-tell-a-maintainer">What I would tell a maintainer</h2><p>If you maintain a project and are thinking about how to prepare it for AI-assisted contributions, this is what I currently believe.</p><ul><li><strong>Consistency is infrastructure.</strong> It helps people understand a project, and it gives machines reliable examples to follow.</li><li><strong>Fix the codebase instead of documenting every exception.</strong> When practical, migrate old conventions rather than asking every future contributor to remember which examples should be ignored.</li><li><strong>Write down the process, not only the style.</strong> A linter can enforce formatting. It can&apos;t explain which reference to choose, which checks prove the work, or which changes don&apos;t belong in the same pull request.</li><li><strong>Make the agent commit to a reference first.</strong> One sentence before any code can prevent an entire incorrect implementation.</li><li><strong>Keep a real reference for numerical work.</strong> Convention can make code look correct. Differential testing against trustworthy ground truth is what tells you whether it behaves correctly.</li><li><strong>Version AI instructions like code.</strong> They become outdated. Give them identifiers, an index, and a history so contributors can tell which guidance is current.</li></ul><h2 id="the-accident-that-paid-off">The accident that paid off</h2><p>I came into this year thinking the interesting question was how to prompt well. I no longer think that is the main question. Prompting is a thin layer over a more basic question: does your project have anything coherent to point at?</p><p>stdlib is unusually good at this, although the benefit to AI was accidental. Years of insisting that related packages look and behave consistently, entirely for the benefit of human contributors, created a useful machine-readable specification as well. The best AI investment the project made happened long before anyone was thinking about AI. It was called &quot;value consistency above all else.&quot;</p><p>That leads to something optimistic. Making a codebase legible to a machine is not separate from making it legible to a person. It is the same work: consistent structure, current conventions, documented processes, and real verification.</p><p>We have always known these things matter. We have not always treated them as urgent. Now something is reading all of it and using what it finds to shape the next contribution.</p><p>Better make it good.</p><hr><p><em>Karan Anand is a core contributor of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>, a JavaScript library for numerical and scientific computing.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[Build for Inheritance]]></title><description><![CDATA[What if the best measure of your impact in open source isn't being needed, but making yourself unnecessary?]]></description><link>https://blog.stdlib.io/build-for-inheritance/</link><guid isPermaLink="false">6a745f1a81c4de9ae6e874fc</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Athan Reines]]></dc:creator><pubDate>Thu, 06 Aug 2026 10:33:54 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/08/gen_splash.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/08/gen_splash.png" alt="Build for Inheritance"><p>We are often rewarded for becoming indispensable, both in our professional and our personal relationships. There is satisfaction in being the person who understands the obscure subsystem, who remembers the history behind a difficult decision, or who can step in and solve the problem that no one else can solve. Being needed can feel like evidence that our work matters, that we matter. But in open source, indispensability is often another name for fragility.</p><p>A release process that only one person understands is not really a process. It is a dependency. A project whose history lives entirely in one person&apos;s memory does not yet possess shared knowledge. And a community that can survive only through the continued sacrifice of a handful of exhausted people is not yet sustainable, no matter how many stars the repository has or how green its dashboards remain.</p><p>This is not a criticism of those people. In fact, if I&apos;m being honest, I&apos;m one of them. More often, it is a testament to how much they have invested and how much they have quietly carried. But it does suggest that good stewardship asks us to do something somewhat counter-intuitive: to care deeply enough about something that it eventually no longer depends on us.</p><p>We care deeply enough whenever we explain not only what we did, but why we did it.</p><p>We do it when we turn an answer we have given ten times into documentation that means no one has to ask the same question an eleventh.</p><p>We do it when we write tests that preserve knowledge of the behavior we intended, when we simplify something clever so another person can understand it, and when we record the context behind a decision rather than allowing that context to disappear into an old chat thread or someone&apos;s memory.</p><p>And perhaps most importantly, we do it when we invite another person into the work before we desperately need their help. When we give someone room to make a decision, to own a release, to lead a conversation, or even to make a mistake without immediately taking the work back from them.</p><p>These actions can be easy to dismiss as overhead. They rarely have the drama of solving the hardest technical problem or shipping the long-awaited feature. There may be no benchmark that captures their value and no release note that gives them proper credit. But they are the actions that turn individual expertise into collective capacity. They are what transform a project from something held together by heroes into something genuinely held in common.</p><p>And this is an important part of what it means for open source to be <em>community-driven</em>.</p><p>It does not mean that everyone must participate in every decision, or that expertise and leadership no longer matter. It means that knowledge, trust, context, and authority are distributed widely enough that the work can be carried by more than a few people and that there is a <a href="https://blog.stdlib.io/the-stakeholder-journey/">visible path</a> for someone new to become one of those people. In open source, <strong>we are always building an inheritance</strong>.</p><p>Someone we may never meet will eventually read the documentation we wrote, encounter the interface we designed, puzzle over the test we left behind, or search through an old issue to understand why the software behaves as it does. That person may never know our name, particularly now in the <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/">age of AI</a>. But they will encounter our judgment. They will discover whether we anticipated their confusion, whether we respected their time, and whether we left enough of a trail for them to understand the work and make it their own.</p><p>As open-source maintainers in a globally distributed world, so much of our shared life exists in code reviews, chat messages, meeting notes, and the moments when one person takes the time to bring another person into context. A shared purpose is not sustained by a <a href="https://blog.stdlib.io/our-mission/">mission statement</a> alone. It is sustained by the small, repeated choices through which we make our knowledge available, make room for others to lead, and ensure that no one has to carry important work entirely alone.</p><p>As engineers, maintainers, designers, project leads, and community leaders, our value is not measured only by what we can accomplish ourselves. It is also measured by what others become able to accomplish because we were here.</p><p>Every project will eventually pass from our hands. Code will be rewritten. Interfaces will change. Roles will change. New people will arrive with ideas that we didn&apos;t anticipate.</p><p>That is not a failure of our stewardship. That is its purpose.</p><p>We should strive to build things worth inheriting and to do the quieter work that makes inheritance possible.</p><p>Because the best proof that we mattered may not be that the work still needs us. It may be that, because of how we cared for it, others can carry it farther than we ever could carry it alone.</p><hr><p><em>Athan Reines is a software engineer at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and core developer of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote>]]></content:encoded></item><item><title><![CDATA[Do you WANT contributors?]]></title><description><![CDATA[If you maintain an open-source project, your contributing file is where you set the terms—of the relationship, of the boundaries, of what you will and won't do. Own your answer. Change it when it stops working.]]></description><link>https://blog.stdlib.io/do-you-want-contributors/</link><guid isPermaLink="false">6a5e7b6681c4de9ae6e874af</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Thu, 23 Jul 2026 15:12:38 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/07/do_you_want_contributors_og.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/07/do_you_want_contributors_og.jpg" alt="Do you WANT contributors?"><p>My open-source origin story goes something like this: <em>I fixed a typo, tweeted some stuff, tripped, fell, and found myself in the inner circle of a large-scale OSS ecosystem with an active, supportive community!</em> It&apos;s trite but true&#x2014;neither universal nor unique. But &quot;inner circle of a large-scale OSS ecosystem&quot; is where I landed, and it&apos;s colored a lot of what I&apos;ve written since&#x2014;including an implicit assumption that you (person who is reading this) are trying to build an ecosystem-scale project too.</p>
<p>POSE (Pathways to Enable Open-Source Ecosystems) has it right there in the name. It expressly describes this shape as the first item in the list of activities it&apos;s meant to support:</p>
<blockquote>
<p>Building and maintaining a distributed community of external contributors who will actively participate in the ongoing development of the open-source product.</p>
</blockquote>
<p>However, this isn&apos;t the only (or even the most common) experience for open-source maintainers or projects. Most projects run on one to three active maintainers.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> Solo isn&apos;t a failure mode; it&apos;s the default.</p>
<p>There&apos;s a wide spectrum of how folks define open source: from &quot;it&apos;s just a license&quot; to &quot;radically open and participatory.&quot; For the rest of this post to land, I need you to accept the license-end as at least legitimate&#x2014;not right, necessarily, just legitimate. There&apos;s no need to re-litigate the decades-long disagreement in order to say that you, as a maintainer, get to decide the bounds of participation in your project.</p>
<p>An open-source project&apos;s first few artifacts are click-through: license (checkbox), <code>README</code> (template), <code>.gitignore</code> (whatever your framework spits out). Then you hit <code>CONTRIBUTING.md</code>&#x2014;the first artifact that actually asks you what you want. Sure, there are best practices and helpful guides for you to follow, but it&apos;s where your project starts having opinions instead of defaults. So it&apos;s worth pausing and really unpacking what you want yours to look like. It&apos;s more than the mechanics of filing issues and submitting pull requests: <code>CONTRIBUTING.md</code> is the foundational framework for the relationship between your project and the unnamed masses who may or may not encounter it.</p>
<p>In fairness, the bare-bones version of contributor guidelines may work just fine for you. Or you and your project may have a version that <em>was</em> working in the past, but no longer feels sufficient.</p>
<p>For years, I had a Venn diagram I used in talks to illustrate what I called the &quot;FOSS happy place&quot;:</p>
<p><img src="https://blog.stdlib.io/content/images/2026/07/foss_happy_place_venn_diagram.png" alt="Do you WANT contributors?" loading="lazy"></p>
<p>It wasn&apos;t a lie&#x2014;it reflected my early experience as a contributor to open source (even if my contributions weren&apos;t code-shaped). It&apos;s still not &quot;wrong,&quot; per se. But it <em>is</em> guilty of radical oversimplification&#x2014;not <em>quite</em> discretizing a continuous variable, but <em>definitely</em> improper dimensionality reduction. Critical features, like time, remuneration, and changing conditions/priorities are nowhere to be seen.</p>
<p>I&apos;m not the only one whose journey was typo fix &#x2192; full-time job/way of life. Kent C. Dodds (among the best in the game of open-source developer experience, in my opinion) describes a similar origin story in <a href="https://kentcdodds.com/blog/how-getting-into-open-source-has-been-awesome-for-me?ref=blog.stdlib.io">How getting into Open Source has been awesome for me</a> (2020). I mention him for two reasons, and neither is throwing him under the bus: one, it&apos;s not just me; two, it&apos;s not dev-rel delusion&#x2014;because (unlike me) he&apos;s a lines-of-code, PR-reviews, engineer-shaped maintainer of a widely used open-source project (<a href="https://testing-library.com/?ref=blog.stdlib.io">Testing Library</a>).</p>
<p>A career in open source isn&apos;t always a heart-eyes-emoji experience. Evan Czaplicki gave a great (aptly named) talk at <em>Strange Loop</em> 2018:  <a href="https://youtu.be/o_4EX4dPppA?si=5PuZgCgQrGFxlOYn&amp;ref=blog.stdlib.io">The Hard Parts of Open Source</a>. The challenges he describes seem somewhat inherent to the craft: you can&apos;t please everyone, conflicts will arise, things that once motivated you will be deeply draining at times. Anyone who&apos;s struggled through a group project in school will recognize the shape. None of that friction is new&#x2014;LLMs didn&apos;t create maintainer burnout. In a 2019 piece by Nadia Eghbal, <a href="https://increment.com/open-source/the-rise-of-few-maintainer-projects/?ref=blog.stdlib.io">&quot;The rise of few-maintainer projects&quot;</a>, she wrote:</p>
<blockquote>
<p>The salient issue for maintainers today is less about growing contributor numbers and more about navigating the flow of developers who are clamoring for their time.</p>
</blockquote>
<p>Sounds familiar, right? AI has ratcheted things up. Maintainers are seriously rethinking what their relationship to their projects and users looks like. And here&apos;s where I return to <code>CONTRIBUTING.md</code> because <em>this</em> is a place where you get to be explicit about the choices you&apos;re making. Even if nobody reads every word (and most people don&apos;t read <code>CONTRIBUTING</code> files at all), writing one is how you set your boundaries in the first place. A <code>CONTRIBUTING.md</code> that reads:</p>
<pre><code class="language-md">No thanks! I&apos;m gonna go it alone.
But feel free to fork and do whatever you like!
</code></pre>
<p>may not be what you&apos;re used to seeing (in fairness, that sentiment is likely carried through the <em>absence</em> of a CONTRIBUTING file), but it&apos;s legitimate. Or, maybe you think it isn&apos;t. Maybe it&apos;s anathema to open source, <strong>BUT</strong> it <em>is</em> a move that <em>someone</em> could make.</p>
<p>Am I recommending it? No. But I&apos;m not you. I&apos;m not everyone. And, importantly, it forces you to acknowledge that you get to set your boundaries and expectations. Again, this is an oversimplification. If you&apos;re maintaining a mature project with a set governance pattern and change-management process, waking up and burning your contributing process to the ground is likely to have serious fallout. But, that doesn&apos;t mean that you can&apos;t experiment (especially if the status quo feels like you&apos;re headed off a cliff.)</p>
<p>Certain projects have, by design, made the bar for contribution high for legitimate reasons. Debian&apos;s already the perfect example of a working gatekeeping mechanism that&apos;s high-demand. You need a sponsor, you find a mentor, you meet in person with someone who can vouch for you&#x2014;as Nadia Eghbal put it, <em>&quot;Debian&apos;s process is built on the need for trust.&quot;</em><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
<p>But Debian is one shape among several. Athan Reines pitched a taxonomy for this: not <em>&quot;how open is your project&quot;</em> on a slider, but <em>&quot;what shape of project are you actually running?&quot;</em> He described four archetypes: the walled castle, the clique, the university, and the hippie commune.</p>
<p><strong>The walled castle (or black box).</strong> You get the code, but the drawbridge stays up. SQLite is the cleanest live example. Their copyright page has a section literally titled &quot;Open-Source, not Open-Contribution,&quot; which says:</p>
<blockquote>
<p>SQLite is open-source, meaning that you can make as many copies of it as you want and do whatever you want with those copies, without limitation. But SQLite is not open-contribution...the project does not accept patches from random people on the internet.</p>
</blockquote>
<p>You can&apos;t misread that. It&apos;s on their homepage. This archetype fits when the maintainer has a firm boundary they don&apos;t want to soften&#x2014;a totally legitimate choice. It also fits when there&apos;s an author who&apos;s just done. The question: Do you want contributors? The answer: No.</p>
<p><strong>The clique.</strong> You need to know the right people to get the secret password. OpenBSD is the best not-pejoratively-clique example I could find. Their <a href="https://www.openbsd.org/hackathons.html?ref=blog.stdlib.io">hackathons page</a> says, plainly: &quot;Hackathon attendees come by invitation only. Some new people in the community who show promise are sometimes invited to see if they have what it takes.&quot; Linux kernel subsystems run on the same social logic at scale: the kernel docs describe a &quot;chain of trust&quot; where pull requests from unknown developers are received warily by subsystem maintainers until they&apos;ve earned their way in. This archetype fits when the cost of misplaced trust is high and the mechanism for establishing trust is &quot;does someone I already trust vouch for you.&quot;</p>
<p><strong>The university.</strong> If you do your homework and score high enough on your exams, we&apos;ll admit you. Debian&apos;s process, above, is the archetypal case: the sponsor and mentor are part of a longer sequence that includes an application manager, a Philosophy &amp; Procedures exam, a Tasks &amp; Skills exam, and then DAM approval (or not). Their own docs are unusually honest about the deal: <em>&quot;the whole NM process is very strict and thorough. This is not meant to discourage people... but it does explain why the New Member process takes so much time.&quot;</em> Kubernetes runs the most numerically explicit ladder I&apos;ve seen: Member (sponsored by two reviewers from different companies), Reviewer (primary on 5+ PRs, reviewed 20+ substantial ones), Approver (30+ merged, nominated by a subproject owner). If you want the stdlib-adjacent case, <a href="https://www.pyopensci.org/?ref=blog.stdlib.io">pyOpenSci</a> has documented onboarding flows for reviewers and editors: guest-editor probation, editor-in-chief nominations, a peer-review process modeled on academic journals. This archetype fits infrastructure that&apos;s load-bearing enough that mistakes are expensive to unwind, and it works if the syllabus is real. (It fails, badly, if the syllabus is a rebrand of &quot;vibes-based homework we won&apos;t tell you the rules of.&quot;)</p>
<p><strong>The hippie commune.</strong> Do you have a pulse? Yes? You&apos;re in. freeCodeCamp basically checks for a pulse and hands you a <code>first timers only</code> label. Their whole cultural stance is &quot;let us help you land your first PR.&quot; I&apos;ve been part of projects like this, and it&apos;s actually onerous in its own way. But, they&apos;re where a lot of folks get started. Without these, the rest of the spectrum loses its future contributors and maintainers. MDN Web Docs runs the same posture on the docs side: their contributing guide is basically &quot;there&apos;s a place for you here, even if your grammar isn&apos;t perfect.&quot; (Wikipedia is the mother of this archetype but isn&apos;t code-shaped, so treat that as a cultural reference, not a technical one.) This archetype fits projects where the marginal contribution has low blast radius, and the real bottleneck is reach or discoverability, not integration cost. It also fits projects whose <em>goal</em> is teaching people to contribute, where the code is almost a byproduct of the mentorship.</p>
<p>In reality, there is, of course, a spectrum&#x2014;and shades of gray as well. A project doesn&apos;t necessarily have to operate in a single mode, either. SQLite runs some clique-shaped review practices under its walled-castle surface. Debian&apos;s university process has real clique-shaped social realities inside it. Any given project can occupy more than one archetype at once&#x2014;a codebase that&apos;s walled-castle at the core and hippie commune at the docs layer, say. And most projects drift between shapes as they age.</p>
<p>I also want to be clear that you&apos;re ALLOWED TO MOVE where your project is at. Is hippie-commune mode failing you in the age of AI slop? Maybe you run an experiment with a more rigorous onboarding (or have folks who have already contributed to the project mentor newcomers through their first PR so that the onus doesn&apos;t always fall on the maintainer.)</p>
<p>There is no more a platonic form for a perfect <code>CONTRIBUTING.md</code> than there is for a universally &quot;perfect&quot; job. The fit is between your project and its contributors. What works for one can be exactly wrong for another.</p>
<p>But here&apos;s why the taxonomy belongs in a piece about what you actually want: it forces you to say the thing out loud. <em>&quot;I want a hippie commune&quot;</em> is a different maintainer future than <em>&quot;I want a university,&quot;</em> and both are different from <em>&quot;I want to keep the code out here but the process in here.&quot;</em> You can&apos;t dodge the question by writing a <code>CONTRIBUTING.md</code> that just describes issue templates. The people who read it (the ~7 who will) can tell which archetype you&apos;re aiming for even when you haven&apos;t named it. Might as well spell it out.</p>
<p>There are pros and cons to the types of friction you introduce&#x2014;selectively inviting who can interact, permanently banning a suspected peddler of AI slop, toggling off the &quot;Issues&quot; section of a repository. But, if the relationship (that between a maintainer and contributors) is evolving in such a way that it feels like it cannot hold, that&apos;s its own type of failure. Neither the maintainer nor &quot;the community&quot; are to <em>blame</em> when things end in a silent resignation or a public crashout&#x2014;but maybe they can be avoided by experimenting with things you hadn&apos;t previously considered as being &quot;worth it.&quot;</p>
<p>Like my old FOSS-happy-place Venn diagram, the chart below doesn&apos;t capture the n-dimensional reality of working in open source. But I&apos;d like to think it&apos;s an improvement. On the x-axis you have maintainer/project (dis)comfort. And the y-axis is something akin to ROI (return on investment)&#x2014;demand from contributors/community/ecosystem.</p>
<p><img src="https://blog.stdlib.io/content/images/2026/07/foss_maintainer_demand_axes.png" alt="Do you WANT contributors?" loading="lazy"></p>
<p>The catch is that you don&apos;t really know where an experiment lands on this chart until you try it&#x2014;not how much it&apos;ll cost you (the x-axis), and not what you&apos;ll get back (the y-axis). That doesn&apos;t mean you have to try everything. But it&apos;s worth paying attention to where things actually fall, rather than where you assumed they would.</p>
<p>Here are some things that we&apos;re trying (or considering taking for a spin):</p>
<ul>
<li>
<p><strong>Code review as the alignment step.</strong> Ed Yang makes the case that <a href="https://blog.ezyang.com/2025/12/code-review-as-human-alignment-in-the-era-of-llms/?ref=blog.stdlib.io">code review is where humans do the alignment work</a> now. As AI takes on more of the implementation, the reviewer&apos;s job shifts away from line-by-line mechanics and toward the big-picture questions&#x2014;does this fit, should it exist, is this the shape we want?</p>
</li>
<li>
<p><strong>Using AI as a market-research companion, not a PR-generation machine.</strong> Instead of <em>AI writes the pull request</em>, it&apos;s <em>AI helps you see the landscape</em>. Feed it the parallel projects&#x2014;for us that&apos;s NumPy, SciPy, Math.js, and friends&#x2014;let it aggregate the patterns everyone else has converged on, and then <em>you</em> decide what fits. Same tool, pointed at <em>what should we build</em> instead of <em>let&apos;s crank out code</em>.</p>
</li>
<li>
<p><strong>Livestreamed PR review.</strong> Twitch, Discord, YouTube&#x2014;pick your poison. Someone watches a maintainer work through a review in real time. The discomfort scales hard depending on who you are (some folks would genuinely rather chew glass than do their job on camera), but it puts other humans in the room at the moment you&apos;re deciding something. And it teaches in both directions: people watching learn what makes a good contribution <em>and</em> what being a maintainer actually takes. It&apos;s knowledge capture without the curation&#x2014;which means it might surface insights you never knew people wanted.</p>
</li>
</ul>
<p>None of this is guaranteed to work. Most of what gets written about open-source communities and contributor experience gets written after the fact&#x2014;after something worked. That means there&apos;s a bottom drawer somewhere full of the things people tried that didn&apos;t (those posts mostly don&apos;t get written.) And even the experiments that did work worked in the <em>specific conditions</em> of that project&#x2014;its size, its maintainers, its users, its moment. Different projects, different fits. This isn&apos;t Wills and Trusts. You can iterate. Your <code>CONTRIBUTING.md</code> can change. Your governance can change. Your mind can change. Whatever you want to do is okay&#x2014;just own it. And if you&apos;re trying something (the thing that&apos;s working, or the thing that isn&apos;t) come tell us about it. We&apos;re figuring it out too.</p>
<hr>
<p class="dev-theme-author-blurb">
    <em>Mara Averick is a developer advocate at <a href="https://quansight.com/?ref=blog.stdlib.io">Quansight</a> and contributor experience lead for <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a>.</em>
</p>
<hr>
<p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p>
<p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p>
<blockquote>
<p>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</p>
</blockquote>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Linux Foundation, OpenSSF, and Harvard LISH. <em>Census III of Free and Open Source Software.</em> December 2024. <a href="https://www.linuxfoundation.org/hubfs/LF%20Research/lfr_censusiii_120424a.pdf?hsLang=en&amp;ref=blog.stdlib.io">https://www.linuxfoundation.org/hubfs/LF Research/lfr_censusiii_120424a.pdf?hsLang=en</a>; GitHub. <em>Octoverse 2025.</em> <a href="https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/?ref=blog.stdlib.io">https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/</a>. <a href="#fnref1" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn2" class="footnote-item"><p>Nadia Eghbal. &quot;The Rise of Few-Maintainer Projects.&quot; <em>Increment</em>, 2019. <a href="https://increment.com/open-source/the-rise-of-few-maintainer-projects/?ref=blog.stdlib.io">https://increment.com/open-source/the-rise-of-few-maintainer-projects/</a>. <a href="#fnref2" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[The Browser Is the Largest Compute Platform on Earth]]></title><description><![CDATA[Modern browsers can run numerical computing, machine learning, and GPU-accelerated workloads locally. Here's why that changes everything.]]></description><link>https://blog.stdlib.io/the-largest-compute-platform-on-earth/</link><guid isPermaLink="false">6a5d8b9881c4de9ae6e8740c</guid><category><![CDATA[Engineering]]></category><dc:creator><![CDATA[Gunj Joshi]]></dc:creator><pubDate>Mon, 20 Jul 2026 15:17:22 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/07/gen_splash.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/07/gen_splash.png" alt="The Browser Is the Largest Compute Platform on Earth"><p>Billions of browsers are already deployed. We just haven&apos;t been using them that way. Think about how most web applications work today: a user interacts with a webpage, that interaction triggers a request to a server somewhere in a data center, the server does the computation, and then the result travels back over the network to display in the browser. This architecture makes sense for many applications, but it introduces latency, requires server infrastructure, and means your data has to leave your device to get anything done.</p><p>There&apos;s another approach: modern browsers have become powerful enough to handle serious computational work right on your device. At <a href="https://hpsf2026.sched.com/event/2Ei8u/bringing-complex-computations-to-browsers-with-open-source-gunj-joshi-stdlib?ref=blog.stdlib.io">HPSFCon 2026</a>, I demonstrated what this looks like in practice: real-time object detection processing webcam feeds, gesture recognition identifying hand signals, and numerical computing operations on large datasets. All of it running entirely in the browser. No servers involved. No network requests. Data never leaves the device.</p><p>This represents a fundamental shift in how we think about computation on the web. For decades, the pattern has been to centralize computation on servers and treat browsers as thin clients that just display results. The early days of computing followed a similar centralization pattern with mainframes like the Z3 and ENIAC. Then came Fortran in the 1950s, which made these machines programmable for scientific work. The development of optimized libraries, such as BLAS in the 1970s and LAPACK in the 1980s, established the foundation for numerical computing that we still use today. Fast forward to now, and we&apos;re seeing browsers gain capabilities that were previously only available on servers: the ability to run compiled code efficiently, to leverage graphics hardware for computation, and to execute machine-learning models locally.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/evolution_timeline.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1600" height="644" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/evolution_timeline.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/evolution_timeline.png 1000w, https://blog.stdlib.io/content/images/2026/07/evolution_timeline.png 1600w" sizes="(min-width: 1200px) 1200px"><figcaption><b><strong style="white-space: pre-wrap;">Evolution timeline.</strong></b><span style="white-space: pre-wrap;"> The timeline of scientific computing: from early mainframes and the development of Fortran, through the creation of foundational libraries like BLAS and LAPACK, to today&apos;s web-native compute capabilities.</span></figcaption></figure><h2 id="the-deployment-problem">The Deployment Problem</h2><p>Traditional deployment follows a simple pattern: client devices send requests over a network to servers, which compute results and send them back. As computations scale, the architecture explodes in complexity. Load balancers, caching layers, cloud storage, and dozens of other components pile on. The infrastructure becomes more sophisticated than the computation itself.</p><p>Consider calculating the absolute value of all elements in an array. The computation is trivial. But, in a client-server architecture, you route it through this entire complex infrastructure. The network round-trip time dwarfs the actual computation time by orders of magnitude.</p><p>This pattern dominates high-performance computing, as well. Supercomputers, GPU clusters, HPC facilities all centralize computation. Users submit jobs through schedulers and wait for results. It works, but centralization is a choice, not a requirement.</p><h2 id="distributed-computing-works-deployment-friction-doesnt">Distributed Computing Works, Deployment Friction Doesn&apos;t</h2><p><a href="https://foldingathome.org/?ref=blog.stdlib.io">Folding@home</a> and <a href="https://setiathome.berkeley.edu/?ref=blog.stdlib.io">SETI@home</a> proved that volunteer computing works at scale. These projects harnessed idle capacity across millions of devices to run molecular simulations and signal analysis. The core insight holds: massive amounts of idle compute capacity sit in devices on desks and in pockets.</p><p>The problem was deployment friction. Users had to explicitly install software, configure their systems, and opt in. That barrier limited adoption to enthusiasts and prevented mainstream use.</p><h2 id="browsers-are-already-everywhere">Browsers Are Already Everywhere</h2><p>Web browsers exist on billions of devices. They require no installation, no external setup, and run on virtually every computing device made in the last decade. The distributed compute platform already exists.</p><p>Browser-based computation solves real problems. When computation happens locally, data never leaves the device. For medical data, financial analysis, or any sensitive information, this is the only acceptable model. Network round-trips are eliminated, so interactive applications respond immediately instead of waiting on network calls. Each browser instance is a compute node, and the infrastructure is already deployed and maintained. Users don&apos;t need to install anything, set up environments, or deal with compatibility issues. They click a URL and the application runs.</p><p>Modern browsers can handle complex computation. The technical foundation is already built.</p><h2 id="the-technical-foundation">The Technical Foundation</h2><p>So, what makes browsers capable of running complex computations? Several key technologies have matured over the past few years, transforming browsers from simple document viewers into powerful computing platforms. Let&apos;s discuss a few of them.</p><h3 id="webassembly-running-high-performance-code-in-the-browser">WebAssembly: Running High-Performance Code in the Browser</h3><p>For years, JavaScript was the only language you could run in a browser. If you had existing code written in C, C++, or Rust&#x2014;especially performance-critical scientific computing libraries&#x2014;you couldn&apos;t use them on the web. <a href="https://webassembly.org/?ref=blog.stdlib.io">WebAssembly</a> changed that. It&apos;s a portable compilation target that lets you take code written in these languages and run it in the browser at speeds approaching what you&apos;d get running natively on your machine.</p><p>The workflow is straightforward. You start with your source code in C, C++, or Rust, which gets compiled to an intermediate representation (typically LLVM IR, which is a common format many compilers use). That intermediate representation then gets converted to WebAssembly&apos;s binary format. The browser downloads this binary and executes it directly. What&apos;s particularly powerful here is that the browser handles all the platform-specific details. Whether your user is on an Intel laptop, an ARM-based smartphone, or an Apple Silicon Mac, the same WebAssembly binary works across all of them.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/webassembly_workflow.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="2000" height="686" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/webassembly_workflow.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/webassembly_workflow.png 1000w, https://blog.stdlib.io/content/images/size/w1600/2026/07/webassembly_workflow.png 1600w, https://blog.stdlib.io/content/images/2026/07/webassembly_workflow.png 2000w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">WebAssembly workflow.</strong></b><span style="white-space: pre-wrap;"> The WebAssembly compilation workflow: source code in languages like C, C++, or Rust gets compiled through an intermediate representation (LLVM IR) into WebAssembly&apos;s portable binary format, which the browser then executes on whatever hardware the user has.</span></figcaption></figure><h3 id="webgpu-tapping-into-graphics-hardware-for-computation">WebGPU: Tapping Into Graphics Hardware for Computation</h3><p>GPUs (graphics processing units) are exceptionally good at certain types of computation, particularly anything that can be parallelized across many small operations. That&apos;s why they&apos;re used for graphics rendering, but it&apos;s also why they&apos;re powerful for scientific computing and machine learning. The problem has always been that GPU programming is vendor-specific. Code you write for an NVIDIA GPU won&apos;t work on an Intel GPU or an Apple GPU. Each vendor has their own APIs, their own optimization techniques, their own quirks. This makes it incredibly difficult to write portable GPU-accelerated code.</p><p><a href="https://www.w3.org/TR/webgpu/?ref=blog.stdlib.io">WebGPU</a> solves this problem for the web. It provides a single, unified API that works across all GPU vendors. Your application code talks to what WebGPU calls a &quot;logical device,&quot; which is an abstraction. The browser then maps that logical device to an adapter for whatever physical GPU the user actually has. That adapter translates your WebGPU calls into the native GPU API (e.g., DirectX, Metal, or Vulkan) and communicates with the driver for that specific hardware. As a developer, you write your code once and it runs on any GPU.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/webgpu_architecture.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="2000" height="1980" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/webgpu_architecture.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/webgpu_architecture.png 1000w, https://blog.stdlib.io/content/images/size/w1600/2026/07/webgpu_architecture.png 1600w, https://blog.stdlib.io/content/images/2026/07/webgpu_architecture.png 2050w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">WebGPU architecture.</strong></b><span style="white-space: pre-wrap;"> The WebGPU architecture: your web application communicates with a logical device, the browser maps that to a hardware adapter, which then talks to the native GPU API and driver. This abstraction means the same code works across NVIDIA, Intel, AMD, and Apple GPUs.</span></figcaption></figure><h3 id="web-workers-using-multiple-cpu-cores">Web Workers: Using Multiple CPU Cores</h3><p>Modern computers have multiple CPU cores, but JavaScript in the browser traditionally runs on a single thread. That means, even if your laptop has eight cores, your JavaScript code can only use one of them. <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API?ref=blog.stdlib.io">Web Workers</a> fix this limitation. They let you spawn independent threads that can run computation in parallel across multiple cores. Your main JavaScript thread can hand off computationally intensive work to these workers, which means heavy computation doesn&apos;t freeze the user interface. The user can still interact with your application while complex calculations happen in the background.</p><h3 id="web-neural-networks-running-ai-models-locally">Web Neural Networks: Running AI Models Locally</h3><p>Most AI-powered applications today work the same way: you send your data to a server, the server runs inference on a machine learning model, and the result comes back. Every query requires a network round-trip. The <a href="https://www.w3.org/TR/webnn/?ref=blog.stdlib.io">Web Neural Network API</a> enables a different approach: running the model directly in the user&apos;s browser.</p><p>This works through a stack of abstractions. Your web application uses a framework such as ONNX Runtime Web, which provides a high-level interface for loading and running models. That framework talks to the WebNN API, which is the browser&apos;s standardized interface for neural-network operations. WebNN then routes those operations to whatever hardware acceleration is available on the device. On Windows, that might be DirectML. On macOS or iOS, it&apos;s Metal Performance Shaders. On devices with specialized neural processing units (NPUs), WebNN can use those directly. If no hardware acceleration is available, it falls back to running on the CPU or even to cloud-based inference.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/webnn_architecture.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1941" height="1317" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/webnn_architecture.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/webnn_architecture.png 1000w, https://blog.stdlib.io/content/images/size/w1600/2026/07/webnn_architecture.png 1600w, https://blog.stdlib.io/content/images/2026/07/webnn_architecture.png 1941w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">Web Neural Network stack.</strong></b><span style="white-space: pre-wrap;"> A web application uses a framework like ONNX Runtime Web to load models, which talks to the WebNN API in the browser. WebNN then routes operations to whatever hardware acceleration is available, whether that&apos;s DirectML on Windows, Metal on Apple devices, or specialized NPU hardware.</span></figcaption></figure><p>What makes this powerful is privacy. When the model runs locally, your queries never leave your device. If you&apos;re using an AI-powered photo editor, your photos stay on your machine. If you&apos;re using a language model for text editing, your documents stay private. Chrome has built an entire infrastructure around this concept, with APIs specifically designed for common AI tasks and pre-loaded models such as Gemini Nano that applications can use without downloading anything.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/chrome_ai_architecture-2.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1434" height="1374" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/chrome_ai_architecture-2.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/chrome_ai_architecture-2.png 1000w, https://blog.stdlib.io/content/images/2026/07/chrome_ai_architecture-2.png 1434w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">Chrome AI infrastructure.</strong></b><span style="white-space: pre-wrap;"> Chrome&apos;s on-device AI infrastructure: applications can access both exploratory APIs (for flexible model loading) and task-specific APIs (for common operations like translation or summarization). These APIs talk to models stored locally, like Gemini Nano, and the browser handles routing inference to the appropriate hardware (GPU, CPU, or NPU).</span></figcaption></figure><h2 id="building-the-software-foundation">Building the Software Foundation</h2><p>Having powerful browser capabilities is one thing. Having the software libraries to make those capabilities accessible is another. This is where the ecosystem comes in.</p><p>Think about how scientific computing works in languages such as Python, R, or MATLAB. Researchers don&apos;t typically write their own matrix multiplication routines or Fourier transform algorithms. They use high-level functions that hide the complexity. When you call <code>numpy.matmul()</code> in Python to multiply two matrices, you&apos;re not executing Python code for the actual multiplication. <a href="https://numpy.org/?ref=blog.stdlib.io">NumPy</a> calls down to highly optimized libraries such as BLAS (Basic Linear Algebra Subprograms) and LAPACK (Linear Algebra Package), which are written in Fortran and C and have been optimized over decades. The high-level language provides the interface, the low-level libraries provide the performance.</p><p>This layered architecture is what makes scientific computing practical. Researchers work at a high level of abstraction, but get performance from heavily optimized low-level code. For browser-based computation to be viable for real work, we need the same kind of ecosystem.</p><p>That ecosystem is emerging. <a href="https://www.tensorflow.org/js?ref=blog.stdlib.io">TensorFlow.js</a> pioneered deep learning on the web by bringing machine learning to the browser with APIs that felt familiar to anyone who&apos;s used TensorFlow in Python. <a href="https://huggingface.co/docs/transformers.js?ref=blog.stdlib.io">Transformers.js</a> builds on the success of TensorFlow.js and leverages the ONNX Runtime to let you load pre-trained language models and run inference locally. <a href="https://ai.google.dev/edge/litert/web?ref=blog.stdlib.io">LiteRT.js</a> brings Google&apos;s cross-platform edge AI runtime to the web, delivering high-performance model inference with WebGPU and WebNN acceleration. <a href="https://stdlib.io/?ref=blog.stdlib.io">stdlib</a> provides the numerical computing foundation: multidimensional arrays, linear algebra routines, statistical functions, and more.</p><p>The Python ecosystem shows how this works at scale. NumPy sits at the foundation, providing arrays and basic operations. On top of NumPy, you have <a href="https://scipy.org/?ref=blog.stdlib.io">SciPy</a> for more advanced scientific computing, Matplotlib for visualization, pandas for data analysis, scikit-learn for machine learning. Then on top of those, you have domain-specific libraries for astronomy (AstroPy), biology (BioPython), image processing (scikit-image), and countless other fields. Each layer builds on the layer below.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/python_ecosystem.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1000" height="1038" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/python_ecosystem.png 600w, https://blog.stdlib.io/content/images/2026/07/python_ecosystem.png 1000w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">Python ecosystem.</strong></b><span style="white-space: pre-wrap;"> The Python scientific computing ecosystem: NumPy provides the foundation (arrays and basic operations), which enables general-purpose scientific libraries (SciPy, Matplotlib, pandas), which in turn enable domain-specific tools for particular fields. Figure adapted from Harris et al. (2020), </span><a href="https://doi.org/10.1038/s41586-020-2649-2?ref=blog.stdlib.io"><span style="white-space: pre-wrap;">Array programming with NumPy</span></a><span style="white-space: pre-wrap;">, </span><i><em class="italic" style="white-space: pre-wrap;">Nature</em></i><span style="white-space: pre-wrap;">, licensed under </span><a href="https://creativecommons.org/licenses/by/4.0/?ref=blog.stdlib.io"><span style="white-space: pre-wrap;">CC BY 4.0</span></a><span style="white-space: pre-wrap;">.</span></figcaption></figure><p>JavaScript is following the same pattern. stdlib provides the foundational layer: the basic data structures (e.g., ndarrays for multidimensional arrays), the core numerical algorithms, and bindings to optimized libraries such as BLAS and LAPACK. Above that foundation, you can build technique-specific libraries for particular methods such as optimization or signal processing, domain-specific libraries for particular fields such as finance or biology, and application-specific tools for particular use cases. The structure is remarkably similar to Python&apos;s approach, which makes sense because both are solving the same problem: how to build a productive scientific computing environment on top of a high-level language.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/stdlib_ecosystem.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1600" height="1393" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/stdlib_ecosystem.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/stdlib_ecosystem.png 1000w, https://blog.stdlib.io/content/images/2026/07/stdlib_ecosystem.png 1600w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">JavaScript ecosystem.</strong></b><span style="white-space: pre-wrap;"> The emerging JavaScript scientific computing stack mirrors Python&apos;s architecture: stdlib provides the foundational primitives (arrays, core algorithms, linear algebra), enabling higher layers of specialization. At the bottom is the JavaScript language itself with its runtime and REPL. stdlib adds plotting and algorithmic primitives. Above that, technique-specific libraries implement particular methods. Then domain-specific libraries address particular fields. Finally, application-specific code solves particular problems.</span></figcaption></figure><h2 id="seeing-it-work">Seeing It Work</h2><p>All of this technology is real and shipping today. At the conference, I ran several live demonstrations to show what browser-based computation actually looks like in practice.</p><h3 id="object-detection-with-mediapipe">Object Detection with MediaPipe</h3><p>The first demo used Google&apos;s <a href="https://developers.google.com/mediapipe?ref=blog.stdlib.io">MediaPipe</a> for real-time object detection. I pointed my webcam at the audience, and the browser identified objects in the video feed in real-time. The entire machine learning model was running locally in the browser. No data was being sent to any server. The webcam feed went directly into the model, the model processed each frame, and the browser drew bounding boxes around detected objects. Zero network requests after the initial page load.</p><p>This isn&apos;t a toy demo. MediaPipe is a production-quality framework used in real applications. Running it entirely in the browser means instant feedback (no network latency) and complete privacy (your webcam feed never leaves your device).</p><h3 id="gesture-recognition">Gesture Recognition</h3><p>The second demo was gesture recognition. The browser watched my hands through the webcam and identified specific gestures: thumbs up, peace signs, open palms. Again, everything ran locally. The model loaded once when the page opened, and then all the inference happened on my machine. No API calls. No external services. Just a machine-learning model executing in the browser, processing video frames in real-time.</p><p>These demonstrations matter because they&apos;re not hypothetical. These are production-quality models running at production-quality speeds, entirely client-side. The technology works today.</p><h2 id="performance-benchmarks">Performance Benchmarks</h2><p>Demonstrations are one thing, but quantitative comparisons tell a clearer story. To make the comparison tangible, I built three separate live demos, one for each implementation approach. Each demo takes the same input image and inverts its colors, running the operation 10 times to measure consistent performance. The <a href="https://stdlib-demo-cs-client.vercel.app/?ref=blog.stdlib.io">first</a> implementation uses traditional client-server architecture: send the image to a server, it processes the image, and then returns the result. The <a href="https://gunjjoshi.github.io/stdlib-demo-pyodide/?ref=blog.stdlib.io">second</a> runs Python with NumPy in the browser via <a href="https://pyodide.org/?ref=blog.stdlib.io">Pyodide</a>, which compiles the entire Python runtime to WebAssembly. The <a href="https://gunjjoshi.github.io/stdlib-demo/?ref=blog.stdlib.io">third</a> uses stdlib for native JavaScript computation. The performance difference is immediately visible: the client-server implementation takes over 2 seconds for 10 iterations, while the browser-based approaches finish in milliseconds.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/image_inversion_comparison_demo.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1919" height="964" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/image_inversion_comparison_demo.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/image_inversion_comparison_demo.png 1000w, https://blog.stdlib.io/content/images/size/w1600/2026/07/image_inversion_comparison_demo.png 1600w, https://blog.stdlib.io/content/images/2026/07/image_inversion_comparison_demo.png 1919w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">Image inversion demo.</strong></b><span style="white-space: pre-wrap;"> Three separate demos running the same image inversion task for 10 iterations: client-server (left) takes 2323.93ms total, Pyodide (center) takes 18.36ms total (along with 3.13s to initialize the python runtime, once), and stdlib (right) takes just 2.08ms total. The visual output is identical across all three, but the performance differences are dramatic.</span></figcaption></figure><p>I tested each implementation across different image sizes, from small 100&#xD7;100 pixel images up to larger 3200&#xD7;3200 images. The pattern holds across all sizes.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/image_inversion_comparison_chart.png" class="kg-image" alt="The Browser Is the Largest Compute Platform on Earth" loading="lazy" width="1410" height="972" srcset="https://blog.stdlib.io/content/images/size/w600/2026/07/image_inversion_comparison_chart.png 600w, https://blog.stdlib.io/content/images/size/w1000/2026/07/image_inversion_comparison_chart.png 1000w, https://blog.stdlib.io/content/images/2026/07/image_inversion_comparison_chart.png 1410w" sizes="(min-width: 720px) 720px"><figcaption><b><strong style="white-space: pre-wrap;">Performance comparison.</strong></b><span style="white-space: pre-wrap;"> Performance comparison across different image sizes: stdlib (purple) consistently outperforms Pyodide (pink) across all image dimensions. Both browser-based approaches dramatically outperform the client-server approach (orange), where network overhead dominates the total time. As images get larger, the gap between client-server and browser-based computation widens even further.</span></figcaption></figure><p>The client-server approach isn&apos;t slow because the server is slow. Network round-trip time dwarfs the actual computation time. For a trivial operation, such as inverting image colors, the time spent moving data over the network completely dominates the time spent actually computing. The infrastructure overhead exceeds the computation itself by 300&#xD7;.</p><p>Pyodide and stdlib both run in the browser, which eliminates network overhead entirely. But even between these two browser-based approaches, there&apos;s a significant difference. Native JavaScript (stdlib) outperforms Python-via-WebAssembly (Pyodide) by 4.6&#xD7;. This makes sense: Pyodide has to run the entire Python interpreter compiled to WebAssembly, which adds overhead. Cross-compiling existing ecosystems to the browser works, and projects such as Pyodide and <a href="https://docs.r-wasm.org/webr/latest/?ref=blog.stdlib.io">WebR</a> bring valuable tools to the web. But native browser-based libraries deliver better performance by avoiding that interpreter overhead.</p><p>The chart shows another important pattern: as image dimensions increase, the performance gap between client-server and browser-based approaches widens. For small images, network overhead is a fixed cost. For larger images, you&apos;re paying both the network cost and the cost of moving more data. Browser-based computation scales better because there&apos;s no network involved.</p><h2 id="python-and-r-in-the-browser">Python and R in the Browser</h2><p>Python and R now run in browsers through impressive engineering efforts. Pyodide brings Python, including NumPy and SciPy, to the browser by compiling the entire Python runtime to WebAssembly. WebR does the same for R. These projects make established ecosystems available on the web, which means researchers can use familiar tools without changing their workflow.</p><p>The tradeoff is performance. These projects compile interpreters to WebAssembly and run them in the browser, which adds overhead. The alternative is writing directly in JavaScript using libraries like stdlib that provide the same numerical primitives as NumPy or SciPy. Both approaches work. Compiled runtimes leverage decades of existing code and let people use tools they already know. Native JavaScript avoids interpreter overhead and delivers better performance for new projects.</p><h2 id="ai-deployment-shifts-to-the-browser">AI Deployment Shifts to the Browser</h2><p>AI model deployment changes fundamentally when you move inference to the browser. The training pipeline stays exactly the same: train on GPU clusters, supercomputers, wherever you train today. But deployment changes completely. Instead of deploying models to cloud servers where users send queries over the network, you load the model into the user&apos;s browser once. After that initial load, users query a local model, not a remote API.</p><p>This shift delivers concrete benefits. Queries never leave the device, which means complete data privacy. There&apos;s no network round-trip, which means low latency for every inference. You don&apos;t need to run massive inference servers, which means reduced infrastructure costs. Training infrastructure stays the same, but deployment becomes radically simpler and completely privacy-preserving.</p><h2 id="where-this-goes">Where This Goes</h2><p>JavaScript has closed the gap for numerical computing. WebAssembly brings near-native performance for compiled languages. WebGPU provides hardware-agnostic GPU acceleration. Web Workers enable true parallelism across CPU cores. WebAI and the Web Neural Network API make on-device inference practical. These aren&apos;t experimental features. They&apos;re shipping in production browsers today.</p><p>The ecosystem is developing rapidly. <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> provides the numerical computing foundation. Higher-level, domain-specific libraries will follow the same pattern we&apos;ve seen in Python, building on these foundational tools to solve specific problems.</p><p>Browsers will become the default platform for privacy-sensitive applications where data cannot leave the device. They&apos;re ideal for interactive tools where latency matters and network round-trips kill the user experience. Educational platforms benefit from zero-friction deployment: students click a link and the application runs, no installation required. Edge computing scenarios where connectivity is intermittent or expensive make browser-based computation the obvious choice.</p><p>Computation is moving from servers to browsers. Not as a replacement for all server-side compute, but as the superior model for specific use cases. The infrastructure is already deployed. Billions of browsers are waiting to compute. You can explore stdlib on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a>, join the conversation on <a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io">Zulip</a>, or watch the <a href="https://youtu.be/rox9LZz_ffI?ref=blog.stdlib.io">full HPSFCon 2026 talk</a> for more details on browser-based scientific computing.</p><hr><p><em>Gunj Joshi is a core developer of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>, a JavaScript library for numerical and scientific computing.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[The Stakeholder Journey: From User to Contributor]]></title><description><![CDATA[Every project eventually faces the same question: who tends to this when the current maintainers can't? It used to have an accidental answer. The Stakeholder Journey is a tool for building an intentional one—identifying where to invest energy to find and cultivate the next generation.]]></description><link>https://blog.stdlib.io/the-stakeholder-journey/</link><guid isPermaLink="false">6a4e100181c4de9ae6e873db</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Wed, 08 Jul 2026 09:20:59 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/07/stakeholder_journey_og_v2@2x.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/07/stakeholder_journey_og_v2@2x.png" alt="The Stakeholder Journey: From User to Contributor"><p>This is the third post in a series on the tools we picked up during I-Corps training, part of the NSF&apos;s Pathways for Open-Source Ecosystems (POSE) program. <a href="https://blog.stdlib.io/open-source-ecosystem-canvas/">The Open-Source Ecosystem Canvas</a> and <a href="https://blog.stdlib.io/mapping-your-ecosystem-and-its-saboteurs/">the Ecosystem and Stakeholder Map</a> both ended on the same question&#x2014;<em>what does it actually take to keep a project alive?</em>&#x2014;and on the observation that the passive window we used to watch our communities through is narrowing. This tool is about looking on purpose instead.</p><h2 id="what-the-journey-is">What the journey is</h2><p>The third tool is the <strong>Stakeholder Journey</strong>, taught to us by <a href="https://www.linkedin.com/in/betsypeters/?ref=blog.stdlib.io">Betsy Peters</a> as part of the go-to-market module of POSE. It maps the path a person takes from never having heard of your project to being one of the people who sustains and leads it:</p><p><strong>Discovery &#x2192; Acquisition &#x2192; Activation &#x2192; First Impact &#x2192; Habit &#x2192; Commitment &#x2192; Ecosystem Leadership.</strong></p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/stakeholder_journey-1.svg" class="kg-image" alt="The Stakeholder Journey: From User to Contributor" loading="lazy" width="1080" height="400"><figcaption><b><strong style="white-space: pre-wrap;">The Stakeholder Journey.</strong></b><span style="white-space: pre-wrap;"> Seven stages run left to right&#x2014;Discovery, Acquisition, Activation, First Impact, Habit, Commitment, and Ecosystem Leadership&#x2014;shaped as a bowtie with First Impact at the narrow center, where the two funnels meet. Each stage carries the stakeholder&apos;s own words for what that moment feels like, from &quot;I find it and it looks relevant&quot; to &quot;I&apos;m willing to help steward it.&quot; </span><i><em class="italic" style="white-space: pre-wrap;">Adapted from Betsy Peters&apos;s go-to-market module, NSF I-Corps POSE program.</em></i></figcaption></figure><p>Most projects, when they think about onboarding at all, think about the left side. <em>Discovery</em> is whether your project shows up&#x2014;in search, in a tutorial, in a coworker&apos;s recommendation, in an AI&apos;s suggested package. <em>Acquisition</em> is whether someone reaches it: installs it, opens the docs, clones the repo. <em>Activation</em> is whether they get past the first wall&#x2014;the README works, the install command runs, the example does what it promised.</p><p>These are the things engineering teams instinctively optimize for. They&apos;re also where most projects stop. <em>We made it easier to install. We rewrote the getting-started guide. We added a Colab badge.</em> All of that work matters. It&apos;s not enough.</p><h2 id="first-impact-is-the-pinch-point">First Impact is the pinch point</h2><p>The pinch point at the center is <strong>First Impact</strong>&#x2014;the moment when a person can say <em>this thing helped me achieve a goal I actually had.</em> Not &quot;I got it running,&quot; but &quot;it did the thing I came here to do.&quot; Without First Impact, nobody moves any further to the right. Everything downstream is gated by it. A project can have a beautiful README and a flawless install and still fail at First Impact, because the person came looking for a result, not a successful build.</p><p>The right side of the journey is what you&apos;re actually building toward. The left&#x2014;Discovery, Acquisition, Activation&#x2014;is about volume and lowering friction. The right is about depth, repeat use, and the people who eventually keep the project alive. And the right side is where the open-source-specific problem hides.</p><p>Everything up to Habit used to be relational by accident. To get the install to work, the example to do the thing, the edge case to resolve, you had to look in someone&apos;s docs, read someone else&apos;s post about hitting the same wall, maybe venture into the somewhat hostile waters of Stack Overflow. None of that was billed as community engagement. It was the cost of getting the thing to work. But every step put you in proximity to other people&apos;s care&#x2014;the maintainer who wrote the doc, the contributor who answered the question three years ago, the stranger who took your duplicate question seriously enough to point you somewhere. The community wasn&apos;t somewhere you went; it was somewhere you passed through to get to the thing you came for. AI dissolves the passage. The install still has to run, the example still has to do the thing&#x2014;but you can now clear those walls without ever touching the artifacts of care that used to do the introducing. <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/">AI and the Invisible Newcomer in Open Source</a> was about what we didn&apos;t know we were relying on until it was gone.</p><p><strong>Habit</strong> is the territory of repeat use&#x2014;the project becomes a default, a known quantity in someone&apos;s toolchain. This can still happen passively. People settle into tools because the tool works and they don&apos;t have to think about it. <em>Someone finds your project, uses it, relies on it&#x2014;and you may never know they exist.</em> Habit users have never been fully visible&#x2014;plenty went unseen even when public friction was the norm&#x2014;but the passive window <a href="https://blog.stdlib.io/mapping-your-ecosystem-and-its-saboteurs/">the Ecosystem and Stakeholder Map</a> named used to make more of them visible than it does now, if not to maintainers then to each other. That visibility to each other matters: people who can see others engaged at the same stage recognize themselves as part of something larger, and what you help build feels worth more than what you just consume.<a><sup>[1]</sup></a> AI absorbs the friction that produced that visibility, which means projects at the Habit stage increasingly have plenty of repeat users and no idea who they are.</p><p><strong>Commitment</strong> is different. Commitment is a crossing&#x2014;the moment a person stops being a user and starts being someone who tends to the project. They file the issue. They open the PR. They answer somebody else&apos;s question. They show up to the call. (Past it lies one more stage, <strong>Ecosystem Leadership</strong>&#x2014;the people willing to help steward the whole thing&#x2014;but Commitment is the crossing everything hinges on.) The transition from Habit to Commitment is the one that has never happened by itself, and it has gotten harder, not easier, as Habit has grown less visible.</p><p>The three conditions that have to be true for someone to make that crossing are uncomfortably soft to talk about, and they matter anyway: people have to feel seen and valued; they need an authentic connection inside the project, not just awareness of it; and they have to participate in creation, not just consumption&#x2014;to feel like they helped shape something, not only consume it.</p><p>None of those happen on their own. Discovery through Habit can be a passive flow. Commitment isn&apos;t.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/07/stakeholder_journey_highlighted-1.svg" class="kg-image" alt="The Stakeholder Journey: From User to Contributor" loading="lazy" width="1080" height="400"><figcaption><b><strong style="white-space: pre-wrap;">Where the relational pinch sits.</strong></b><span style="white-space: pre-wrap;"> Same seven-stage bowtie, with Commitment and Ecosystem Leadership highlighted in yellow. First Impact is a utility pinch&#x2014;get the install working, get the example to do the thing. The pinch past it is different: it only clears when an actual person reaches out, which is why Commitment and Ecosystem Leadership are marked here as the open-source-specific challenge.</span></figcaption></figure><h2 id="who-does-the-inviting">Who does the inviting</h2><p><a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/">AI and the Invisible Newcomer in Open Source</a> landed on invitation: that crossing into a community almost never happens by accident, and that there&apos;s usually a person with standing who reaches out and makes it personal. The journey is where you can see exactly what that act does. Invitation is the force at the Commitment crossing&#x2014;the one transition no amount of passive flow will carry someone across.</p><p>Among the people we interviewed who&apos;d already crossed that chasm&#x2014;the maintainers, the stewards&#x2014;the story came back the same shape. Nobody starts their open-source journey with a grand plan to maintain a project. You stumble in. You find something that works. You stick around because it keeps working. You read an issue, then another. You answer one question. Somewhere along the way, almost without noticing, you&apos;re doing it because the work itself matters to you. That shift&#x2014;from user to contributor, from consumer to caretaker&#x2014;doesn&apos;t happen by accident. There has to be someone with standing already inside the community who reaches out, who makes it personal, who says: <em>we see you, and there&apos;s a place for you here.</em></p><p>So who does the inviting?</p><p>The people in the inner rings. The scaffold <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/">AI and the Invisible Newcomer in Open Source</a> laid out&#x2014;old-timers at the center, casual visitors at the outermost edge, a labeled trajectory pulling inward through intermediate roles&#x2014;describes how any community works, and it pins down where the inviting has to come from. The people whose attention pulls that trajectory are the ones with the standing to do it. It&apos;s the same point the communities-of-practice literature has made for decades<a><sup>[2]</sup></a>&#x2014;that the journey from periphery to center is a social one, needing paths and people willing to guide&#x2014;but the journey map is where you can finally put your finger on the step it happens at.</p><p>But &quot;the inner rings do the inviting&quot; hides a more specific mechanism. Invitation from the center&#x2014;the maintainer who reaches out, the steward who notices&#x2014;is rare and high-signal and doesn&apos;t scale. The daily work of pulling someone inward, the work that makes the next step look like a step rather than a leap, is done by the person <em>one</em> ring ahead of them. The trajectory the figure draws as a single arrow from edge to center is, in practice, a relay of short pulls. The near-peer who just crossed the same threshold is a better guide than the expert who crossed it years ago&#x2014;not because they know more, but because they can still see where it was hard.<a><sup>[3]</sup></a></p><p>That mechanism needs density. A community where the next ring is visibly populated&#x2014;where someone at Habit can see other people doing what Commitment looks like&#x2014;can pull contributors along it. A community where the rings are sparse can&apos;t. The path doesn&apos;t close; it stops being visible from where most people are standing. Recent empirical work on aging OSS projects finds that sustained substantive engagement is what keeps the trajectory functioning over time, while passive attention loses its predictive power as a project ages.<a><sup>[4]</sup></a> The failure mode is quiet: the dashboards stay green; the path just stops being navigable.</p><p>Invitation is how the trajectory begins. Belonging is what carries it forward. And belonging&#x2014;not a tutorial, not your <code>CONTRIBUTING.md</code>&#x2014;is what turns a user into a contributor.</p><h2 id="three-questions-for-every-project">Three questions for every project</h2><p>If there&apos;s a single way to summarize what the canvas, the map, and the journey are for, it&apos;s that they make three questions impossible to leave unanswered.</p><ol><li><strong>Have you mapped your ecosystem&#x2014;including the saboteurs?</strong> Or are you assuming you already know who&apos;s in your world? Most projects know their power users by name and their critics by reputation, but can&apos;t actually draw the network of incentives around them. The map exists because the people you haven&apos;t named are still acting on your project&#x2014;funders, competitors, downstream maintainers, model providers, the people quietly recommending a different library in every Slack you can&apos;t see. If you can&apos;t see them, you can&apos;t steer around them, and they will steer anyway.</li><li><strong>Are you designing your contributor pipeline&#x2014;or assuming it will appear?</strong> It used to appear on its own&#x2014;the byproduct of public friction that <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/">AI and the Invisible Newcomer in Open Source</a> was about, and the one that&apos;s weakening. Designed programs help, but they aren&apos;t a substitute: even Google Summer of Code, about as structured an onramp as open source has, sees only around 45% of true newcomers<a><sup>[5]</sup></a> who keep contributing after the program ends, and most never arrived intending to become maintainers in the first place.<a><sup>[6]</sup></a> So, if you want a next generation of people who can run your project after you, the activities friction used to produce for free have to be built on purpose now: invitation, mentorship, and a path from user to contributor to maintainer with visible, named rungs that people know exist and can actually reach for. Mentorship in particular has more measurable shape than it usually gets credit for: in the most thorough study to date<a><sup>[7]</sup></a> of mentors in Google Summer of Code, Tan and colleagues find that the heaviest load falls in proposal evaluation and the first weeks of onboarding&#x2014;phases you can design around once you know they&apos;re the binding ones.</li><li><strong>Is your community built for survivorship?</strong> Not just for how things worked before. The shape of the world a project&apos;s community grew up in is not the shape of the world the next one will. The question isn&apos;t whether the old onramps are still working; it&apos;s whether you&apos;ve designed onramps that still work when the old ones don&apos;t.</li></ol><p>The reason to ask these isn&apos;t to add another set of metrics to a dashboard. It&apos;s because the projects that will still matter in ten years&#x2014;the ones that are still vibrant and alive&#x2014;will be the ones where someone chose to tend to the community with the same rigor they brought to the code.</p><p>The code is the part that&apos;s easy to measure. The community is the part that decides whether the code still matters.</p><hr><p><em>Mara Averick is a developer advocate at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and contributor experience lead for </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote><hr><ol><li>Strayhorn, T. L. (2018). <em>College students&apos; sense of belonging: A key to educational success for all students</em> (2nd ed.). Routledge. <a href="https://doi.org/10.4324/9781315297293?ref=blog.stdlib.io">https://doi.org/10.4324/9781315297293</a> <a>&#x21A9;&#xFE0E;</a></li><li>Sholler, D., Steinmacher, I., Ford, D., Averick, M., Hoye, M., &amp; Wilson, G. (2019). Ten simple rules for helping newcomers become contributors to open projects. <em>PLOS Computational Biology</em>, 15(9): e1007296. <a href="https://doi.org/10.1371/journal.pcbi.1007296?ref=blog.stdlib.io">https://doi.org/10.1371/journal.pcbi.1007296</a> <a>&#x21A9;&#xFE0E;</a></li><li>On the curse of expertise&#x2014;the structural blind-spot experts develop about what was hard for them years ago: Hinds, P. J. (1999). The curse of expertise: The effects of expertise and debiasing methods on prediction of novice performance. <em>Journal of Experimental Psychology: Applied</em>, 5(2), 205&#x2013;221. <a href="https://doi.org/10.1037/1076-898X.5.2.205?ref=blog.stdlib.io">https://doi.org/10.1037/1076-898X.5.2.205</a>. See also Nathan, M. J., &amp; Petrosino, A. (2003). Expert blind spot among preservice teachers. <em>American Educational Research Journal</em>, 40(4), 905&#x2013;928. <a href="https://doi.org/10.3102/00028312040004905?ref=blog.stdlib.io">https://doi.org/10.3102/00028312040004905</a>. <a>&#x21A9;&#xFE0E;</a></li><li>Kaushik, M., &amp; Chahal, K. K. (2026). Community engagement and the lifespan of open-source software projects. <em>Information and Software Technology</em>. <a href="https://doi.org/10.1016/j.infsof.2025.107914?ref=blog.stdlib.io">https://doi.org/10.1016/j.infsof.2025.107914</a> &#x2014; sustained substantive participation keeps aging projects alive; passive attention loses predictive power as a project ages. Companion death-spiral dynamics paper: Kaushik, M., &amp; Chahal, K. K. (2026). The death spiral of open source projects: A post-mortem analysis of pull request workflow dynamics. <em>Journal of Systems and Software</em>, 240, 112942. <a href="https://doi.org/10.1016/j.jss.2026.112942?ref=blog.stdlib.io">https://doi.org/10.1016/j.jss.2026.112942</a>. <a>&#x21A9;&#xFE0E;</a></li><li>Silva, J. O. dos, Wiese, I., German, D. M., Steinmacher, I., &amp; Gerosa, M. A. (2017). How long and how much: What to expect from Summer of Code participants? <em>ICSME 2017.</em> <a href="https://doi.org/10.1109/ICSME.2017.81?ref=blog.stdlib.io">https://doi.org/10.1109/ICSME.2017.81</a> <a>&#x21A9;&#xFE0E;</a></li><li>Silva, J. O., Wiese, I., German, D. M., Treude, C., Gerosa, M. A., &amp; Steinmacher, I. (2020). Google Summer of Code: Student motivations and contributions. <em>Journal of Systems and Software</em>, 162, 110487. <a href="https://doi.org/10.1016/j.jss.2019.110487?ref=blog.stdlib.io">https://doi.org/10.1016/j.jss.2019.110487</a> &#x2014; surveys of 141 students and 53 mentors plus ten confirmatory interviews found most students enter GSoC seeking an enriching experience or skill development, not long-term project membership. <a>&#x21A9;&#xFE0E;</a></li><li>Tan, X., Zhou, M., &amp; Zhang, L. (2023). Understanding mentors&apos; engagement in OSS communities via Google Summer of Code. <em>IEEE Transactions on Software Engineering</em>, 49(5), 3106&#x2013;3130. <a href="https://doi.org/10.1109/TSE.2023.3242415?ref=blog.stdlib.io">https://doi.org/10.1109/TSE.2023.3242415</a>; they catalog 41 distinct challenges and 52 strategies across all phases. <a>&#x21A9;</a></li></ol>]]></content:encoded></item><item><title><![CDATA[Mapping Your Ecosystem (and Its Saboteurs)]]></title><description><![CDATA[Naming everyone in your open-source ecosystem—both competitors and colleagues—and following where value flows.]]></description><link>https://blog.stdlib.io/mapping-your-ecosystem-and-its-saboteurs/</link><guid isPermaLink="false">6a3f7eea81c4de9ae6e8737a</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Sat, 27 Jun 2026 07:55:37 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1586936893354-362ad6ae47ba?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEyNnx8bWFwfGVufDB8fHx8MTc4MjU0NjQyN3ww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1586936893354-362ad6ae47ba?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEyNnx8bWFwfGVufDB8fHx8MTc4MjU0NjQyN3ww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Mapping Your Ecosystem (and Its Saboteurs)"><p>This is the second post in a series on the tools we picked up during I-Corps training, part of the NSF&apos;s POSE (Pathways to Enable Open-Source Ecosystems) program. The <a href="https://blog.stdlib.io/open-source-ecosystem-canvas/">first post</a> covered the Open-Source Ecosystem Canvas&#x2014;who you&apos;re building for, what it takes, and how you sustain it. This one is about drawing the network those answers live inside.</p><p>The map changes as you learn. Like the canvas, it surfaces the assumptions you didn&apos;t know you were making.</p><h2 id="what-the-map-is">What the map is</h2><p>The tool is the <strong>Ecosystem and Stakeholder Map</strong>. Your project doesn&apos;t operate in a silo; the map simplifies the world around it enough to look at. The first thing it asks you to do is something surprisingly difficult: name everyone who is in your world.</p><p>Not just your users.</p><p>Not just your contributors.</p><p><em>Everyone.</em></p><p>Our map has a box labeled &quot;Saboteurs&quot;&#x2014;a category the I-Corps program asks every team to fill in. The label is sharper than the function. In the framing, &quot;saboteurs&quot; is one of six stakeholder categories (among them competitors, partners, users, contributors, and influencers), not a class of villains.</p><p>Many of the people in it are friends and colleagues whose work is good and valuable, and we&apos;re not trying to deny that. The point of the box is closer to <em>what else is around here that could take our place.</em> These are the projects and people who inform what we do&#x2014;who could plausibly substitute for us, who is shaping the conversation around what we build. Knowing how you fit in that competitive landscape is how you figure out where your project adds value. Leave the box blank and you lose your read on where you stand, and on what it will take to keep standing there. And the box isn&apos;t hypothetical: of our hundred-odd interviews, fourteen were with people who belonged in it&#x2014;alongside industry and academic users, contributors, downstream adopters, and funders.</p><p>And not every saboteur is a competitor. One of this year&apos;s CHI papers names a different kind&#x2014;&quot;Invisible Saboteurs&quot;<a><sup>1</sup></a>&#x2014;high-sycophancy LLMs that made users <em>less</em> likely to correct their misconceptions, with a majority unable to detect that AI was being agreeable. The most consequential saboteur in your ecosystem may not be another project at all. It may be a tool that agrees with everyone, including your newest contributor, at the moment they&apos;re forming the wrong mental model.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://blog.stdlib.io/content/images/2026/06/stdlib_ecosystem_map.svg" class="kg-image" alt="Mapping Your Ecosystem (and Its Saboteurs)" loading="lazy" width="1536" height="828"><figcaption><b><strong style="white-space: pre-wrap;">Ecosystem &amp; stakeholder map.</strong></b><span style="white-space: pre-wrap;"> stdlib sits at the center as the product the whole ecosystem revolves around, with four stakeholder clusters around it&#x2014;</span><b><strong style="white-space: pre-wrap;">Saboteurs</strong></b><span style="white-space: pre-wrap;">, </span><b><strong style="white-space: pre-wrap;">Funders</strong></b><span style="white-space: pre-wrap;">, </span><b><strong style="white-space: pre-wrap;">Users</strong></b><span style="white-space: pre-wrap;">, and </span><b><strong style="white-space: pre-wrap;">Contributors</strong></b><span style="white-space: pre-wrap;">&#x2014;and the </span><b><strong style="white-space: pre-wrap;">Technical Steering Committee</strong></b><span style="white-space: pre-wrap;"> governing from below. The labeled arrows are the point: they show how value flows. Small muted tallies in each corner record stakeholder-interview counts from the NSF I-Corps program&#x2014;a filled dot marks completed interviews, a ring the target. Emeritus deliberately sits outside the Contributors boundary: those maintainers have left the active pool. </span><i><em class="italic" style="white-space: pre-wrap;">Note: not all ecosystem participants are shown&#x2014;downstream library authors and derivative projects are omitted for clarity.</em></i></figcaption></figure><p>One small discipline that pays off here: map people before organizations, and notice your blind spots. The world your project sits in is bigger than the people you already know to name. The segments where you can only name one or two&#x2014;or none&#x2014;are where your understanding is thinnest and your confidence is least earned. They&apos;re also where opportunities tend to hide.</p><h2 id="the-arrows-matter-as-much-as-the-nodes">The arrows matter as much as the nodes</h2><p>The map isn&apos;t only a roster of who&apos;s there. It&apos;s a steering tool: arrows show how value flows. Where it comes from, where it goes, where it leaks.</p><p>We tend to talk about open-source value in concrete terms. The software is free. The tooling saves time. The license costs nothing. Those are real, and they belong on the map. But there&apos;s a less tangible current, too: <strong>reputation and belonging</strong>. Standing. The regard of people whose regard means something.</p><p>That&apos;s always mattered. It matters more now. As AI makes writing code faster and cheaper, the thing that doesn&apos;t get cheaper is trust&#x2014;because trust requires a real other with the standing to withhold it. A system engineered to validate you can satisfy the <em>form</em> of recognition without the <em>substance</em><a><sup>2</sup></a>; a friend whose approval costs them nothing isn&apos;t really a friend<a><sup>3</sup></a>. When you weigh in on a decision, people listen&#x2014;not because of your commit count, but because of what you&apos;ve earned in the community over time. <em>That is a value proposition.</em> It belongs on your map alongside the funding arrows.</p><h2 id="what-the-canvas-and-the-map-are-both-asking">What the canvas and the map are both asking</h2><p>Both are asking the same question.</p><p>What does it actually take to keep an open-source community alive?</p><p>Part of the answer turns on a distinction that&apos;s easy to miss. Your <em>code</em> can be copied, distributed, and shared without being depleted&#x2014;if anything, it grows in value the more it&apos;s shared. Your <em>community</em> is the opposite. Time, attention, and trust are finite, spent in the giving, and not replenished automatically&#x2014;which is why burnout is a resource-depletion problem. The code can largely sustain itself. The community has to be designed. The code is free; the community isn&apos;t.</p><p>That&apos;s why the honest answer to what it takes has three levels, and most projects only think seriously about the first one.</p><p><strong>Level 1 is code.</strong> Does it run. Does it build. Are the tests green. Is the dependency graph manageable. This is the level that maintainers are trained to think about, that funders understand, that GitHub measures for you. Almost every &quot;sustainability&quot; conversation in open source starts and ends here.</p><p><strong>Level 2 is governance.</strong> Who decides. How decisions get made. What happens when the founder steps back, or burns out, or moves on. Whether there&apos;s a process for contention that doesn&apos;t depend on a single person being in the room. Some projects take this seriously; many don&apos;t, and by the time they need to, the people who would have done the work have already left.</p><p><strong>Level 3 is community.</strong> Who actually shows up. Whether new people are arriving, and whether the people already there are staying. Whether the project has a story about itself that someone could find their way into. This is where projects die&#x2014;not when the code breaks, but when nobody&apos;s left who cares enough to fix it. The empirical record on project abandonment bears this out. A post-mortem of 104 deprecated GitHub projects found the recurring failure modes were community-side, not code-side: loss of the lead maintainer, lack of time or interest from main contributors, displacement by a competitor <a><sup>4</sup></a>. The live-project picture mirrors this: in a study of nearly 34,000 active GitHub repos, what predicted longevity wasn&apos;t stars, watchers, or workflow efficiency but active community engagement on issues&#x2014;and that predictive power <em>intensifies</em> as projects age <a><sup>5</sup></a>. Both are proxies&#x2014;measuring issue activity and deprecation events, not the sense of belonging that actually keeps a community alive. But anyone who&apos;s worked in one knows the research is pointing at the right wall.</p><p>The asymmetry matters here. AI is good at producing the artifact and bad at producing the attachment, because attachment is a byproduct of the labor AI removes. The merged PR, the answered question, the completed exercise can all look identical whether a person grew through them or skipped them&#x2014;and the difference, invisible on the artifact graph, is the entire ballgame for whether your community has a next generation.</p><p>For a long time, Level 3 had a window we could look through without thinking about it. Stack Overflow. GitHub issues. Mailing lists. Forum threads. We could see&#x2014;passively, almost automatically&#x2014;whether the community was still there, because people kept showing up to ask questions in public.</p><p>That&apos;s the window <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/"><em>AI and the Invisible Newcomer in Open Source</em></a> was about. It&apos;s narrowing.</p><p>The point of what comes next isn&apos;t to mourn the window. It&apos;s to notice that if the passive view is gone, the active one has to be designed. What used to happen by accident is now deliberate work. That&apos;s the Stakeholder Journey, which I will discuss in the next post in this series.</p><h2 id="notes">Notes</h2><p><a>1.</a> Bo, J. Y., Kazemitabaar, M., Deng, M., Inzlicht, M., &amp; Anderson, A. (2026). Invisible saboteurs: Sycophantic LLMs mislead novices in problem-solving tasks. In <em>CHI &apos;26: Proceedings of the 2026 CHI Conference on Human Factors in Computing Systems</em>. <a href="https://doi.org/10.1145/3772318.3791365?ref=blog.stdlib.io">https://doi.org/10.1145/3772318.3791365</a></p><p><a>2.</a> Jacobs, K. A. (2024). Digital loneliness&#x2014;Changes of social recognition through AI companions. <em>Frontiers in Digital Health</em>, 6, 1281037. <a href="https://doi.org/10.3389/fdgth.2024.1281037?ref=blog.stdlib.io">https://doi.org/10.3389/fdgth.2024.1281037</a></p><p><a>3.</a> Sparrow, R., &amp; Brown, J. (2026). Against imaginary friends: Why digital companions are no solution to social isolation. <em>Communications of the ACM</em>, 69(2), 60&#x2013;68. <a href="https://doi.org/10.1145/3750037?ref=blog.stdlib.io">https://doi.org/10.1145/3750037</a></p><p><a>4.</a> Coelho, J., &amp; Valente, M. T. (2017). Why modern open source projects fail. In <em>Proceedings of the 2017 11th Joint Meeting on Foundations of Software Engineering (ESEC/FSE 2017)</em> (pp. 186&#x2013;196). <a href="https://doi.org/10.1145/3106237.3106246?ref=blog.stdlib.io">https://doi.org/10.1145/3106237.3106246</a></p><p><a>5.</a> Kaushik, M., &amp; Chahal, K. K. (2026). Community engagement and the lifespan of open-source software projects. <em>Information and Software Technology</em>. <a href="https://doi.org/10.1016/j.infsof.2025.107914?ref=blog.stdlib.io">https://doi.org/10.1016/j.infsof.2025.107914</a></p><hr><p><em>Mara Averick is a developer advocate at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and contributor experience lead for </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote>]]></content:encoded></item><item><title><![CDATA[The Open-Source Ecosystem Canvas]]></title><description><![CDATA[An ecosystem canvas makes an open-source project say who it's really for. Here's what ours surfaced about stdlib's value propositions for contributors and users—and why they're not the same.]]></description><link>https://blog.stdlib.io/open-source-ecosystem-canvas/</link><guid isPermaLink="false">6a324335ed2315029621f2a6</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Wed, 17 Jun 2026 13:00:39 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/06/gen_splash-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/06/gen_splash-1.png" alt="The Open-Source Ecosystem Canvas"><p>This is the first in a series of posts on the tools we picked up during I-Corps training&#x2014;part of the NSF&apos;s POSE (Pathways to Enable Open-Source Ecosystems) program&#x2014;and what each one showed us about <a href="https://stdlib.io/?ref=blog.stdlib.io">stdlib</a>&apos;s ecosystem. It picks up where <a href="https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/"><em>AI and the Invisible Newcomer in Open Source</em></a> left off: that post was the diagnosis&#x2014;the visible friction open-source communities have always relied on is being absorbed by AI, and what&apos;s eroding underneath is how newcomers get seen. It closed on a question&#x2014;<em>what signals are you still relying on that may no longer be reaching you?</em>&#x2014;and a promise to come back to the tools we&apos;ve been using to ask it.</p><p>One discipline ran through the whole program, and it&apos;s worth stating up front because it decides whether these tools work or just flatter you: you don&apos;t pitch&#x2014;you examine. You&apos;re there to learn what&apos;s true about your project, not to sell anyone on what it already is. A canvas you fill in to feel good about yourself is worthless.</p><p>How you do the examining is on a sliding scale. The program ran on roughly 100 interviews in seven weeks&#x2014;brutal, and not what most teams will (or should) try to repeat. The canvas works at lower fidelity too: a team running its own prompts honestly, a handful of conversations with people in your orbit, even one careful pass with the people already in the room. The discipline is what travels; the interview count scales to whatever you can get.</p><h2 id="what-the-canvas-is">What the canvas is</h2><p>The program led with the <strong>Open-Source Ecosystem Canvas</strong>: a grid of cells you fill in, one per facet of the project&#x2014;who it&apos;s for, what value they get, how you reach them, what it costs, how it&apos;s funded. It&apos;s adapted from the Business Model Canvas, and the adaptation is the interesting part. An open-source project doesn&apos;t have customers in the SaaS sense, and the people who <em>use</em> it, <em>build</em> it, and <em>fund</em> it are often three different groups. So the canvas makes you account for value role by role, instead of letting you collapse everyone into a single &quot;user.&quot; Most of what follows came from that one move.</p><figure class="kg-card kg-image-card"><img src="https://blog.stdlib.io/content/images/2026/06/ose_canvas_blank.svg" class="kg-image" alt="The Open-Source Ecosystem Canvas" loading="lazy" width="976" height="550"></figure><p>What makes the canvas different from a plan is that nothing on it is a promise. Every cell is a hypothesis&#x2014;what you suspect is true, written down where you can look at it, not what you&apos;ve committed to deliver. That&apos;s a strange kind of freedom: a canvas is a place to be tentatively wrong on purpose. A blank brainstorm follows your attention&#x2014;you end up circling the parts of the project you already think about. The canvas fixes the prompts in advance, so it asks about the cells you&apos;d never have raised yourself. Those are usually the ones worth lingering on.</p><h2 id="what-ours-surfaced">What ours surfaced</h2><p>So here&apos;s ours. We&apos;ve worked on it and it&apos;s still unfinished&#x2014;which is what a canvas is supposed to be: some cells are firmer than others, and a few are mostly still questions. Doing it turned up things we&apos;d been quietly avoiding: about sustainability, about the gap between who we were building for and who we said we were building for, about what the next ten years of stdlib look like if we change nothing.</p><figure class="kg-card kg-image-card"><img src="https://blog.stdlib.io/content/images/2026/06/stdlib_ose_canvas_snapshot.svg" class="kg-image" alt="The Open-Source Ecosystem Canvas" loading="lazy" width="976" height="550"></figure><p>Two cells did most of the surfacing.</p><p><strong>Value Propositions.</strong> This cell asks you to think beyond the fact that you&apos;re shipping &quot;free&quot; code, and name what value each kind of person gets from the project&#x2014;and the moment we took that seriously, one answer split into several. Contribution as a r&#xE9;sum&#xE9; line and a career stepping-stone? Numerical computing that runs on anything with a browser, no server or back end required? Familiar data tooling for people arriving from Python or R? These don&apos;t reduce to a single pitch, and forcing them into one would have buried the actual finding: some of these are reasons people <em>use</em> stdlib, some are reasons people <em>contribute</em> to it, and those turned out not to be the same people.</p><p><strong>Community Members.</strong> This cell asks you to list who&apos;s actually there. We wrote down the obvious roles&#x2014;core maintainers, Google Summer of Code (GSoC) alumni who stuck around, ecosystem package authors, industry users, the JavaScript developers who&apos;d steered clear of statistics because the tools weren&apos;t there&#x2014;and a handful more. Then we noticed a phrase we&apos;d typed almost without thinking, parenthetical, next to casual contributors: <em>usually non-users.</em> That aside was doing more work than the rest of the list. For a lot of open-source projects, contributors are a subset of users&#x2014;they show up because they hit a limitation in something they depend on. For stdlib, that&apos;s frequently not the case. A large share of the people opening pull requests aren&apos;t people using JavaScript for numerical computing in their own work; many arrive through GSoC and other on-ramps, and they&apos;re building the thing more than using it. Once that&apos;s written down, you can&apos;t un-see it&#x2014;and you can&apos;t describe both groups honestly on one grid. We ended up needing two canvases, one per community, because the questions that matter for the people who <em>build</em> stdlib aren&apos;t the questions that matter for the people who <em>depend on</em> it. A project where contributors and users overlap heavily might never need that split&#x2014;the canvas surfaces what&apos;s true for you, not a particular answer. And the canvas keeps asking for more precision than its grid can hold&#x2014;&quot;users&quot; isn&apos;t one group either, which is where the rest of the series picks up.</p><p>It&apos;s worth saying why an exercise like this earns its discomfort. The ground under open source is moving fast enough that the honest reactions are either to keep shipping and trust it&apos;ll sort itself out, or to decide the whole thing isn&apos;t worth the trouble anymore. Both are real, and both can be self-protective if left unexamined. A canvas is the examination&#x2014;stopping to look at what you&apos;re actually doing and who it&apos;s for, before you decide. And if you decide parts of it aren&apos;t worth sustaining, that&apos;s a decision made on purpose rather than by default&#x2014;different from throwing up your hands. And if you decide it <em>is</em> worth sustaining, it shows you where the work has to change by design&#x2014;the note the last post ended on: the on-ramps that used to happen by accident increasingly have to be built.</p><p>You don&apos;t need ours, though&#x2014;you need yours. That&apos;s the whole point: filling one in surfaces the choices you&apos;d otherwise leave implicit.</p><h2 id="what-to-ask-once-its-filled-in">What to ask once it&apos;s filled in</h2><p>A filled canvas isn&apos;t the deliverable&#x2014;the conversations it forces are. The useful questions read <em>across</em> cells, not down a single column&#x2014;for us, that means questions that straddle the split between non-user contributors and the users they build for. The best of them are the ones you can&apos;t answer without going and asking someone. A few we&apos;re sitting with:</p><ul><li><strong>Do our operations actually deliver the value we promise contributors?</strong> Our Operations-and-Activities cell lists GSoC as the contributor pipeline, with monthly newcomer sessions and office hours as the mentorship structure. Our Value Propositions include mentorship and recognition, and contribution as a career stepping-stone. Do those activities close that loop&#x2014;does a GSoC contributor leave having gotten what we say they&apos;ll get?</li><li><strong>Do users&apos; value propositions match the ones we think we&apos;re offering?</strong> Our Value-Propositions cell mixes contributor value (r&#xE9;sum&#xE9;-builder, mentorship) with user value (browser-native results, familiar tooling for Python/R developers, no back end). This is the one you pair with interviews. What you think you&apos;re building and what your users think you&apos;re building are not necessarily the same thing.</li><li><strong>Are our go-to-market activities still pointed at the people we want?</strong> Our Go-to-Market cell was built for a pre-AI world: Bluesky posts, conference talks, SEO, cross-posting, video onboarding. If AI is absorbing those accidental on-ramps, which of those activities still land&#x2014;and which need to be jettisoned and replaced with something else? One channel is sliding into gatekeeper territory: AI-mediated discovery is increasingly how developers find their way to a numerical library, and the canvas&apos; flat Community Members cell can&apos;t see it. Another tool from the program&#x2014;Ecosystem Segmentation, which we&apos;ll get to later in this series&#x2014;splits User from Decision Maker from Gatekeeper, and that split is what makes the gatekeeper visible.</li><li><strong>Are the resources keeping this alive still going to be there?</strong> Open-source projects run on time, money, and effort that someone commits to them&#x2014;written down by name in the canvas&apos; Funding-Sources, In-Kind Support, and Costs cells. For us right now, that&apos;s an NSF POSE grant, in-kind labor from sponsoring companies, and recurring donations. AI has already changed the shape of open-source communities, not just for newcomers&#x2014;and the labor that goes into the code itself isn&apos;t immune. There&apos;s a physics teacher&apos;s line in Svetlana Alexievich&apos;s <em>Secondhand Time</em> we keep returning to: money solves all problems, even differential equations. Particularly sharp when the differential equations are the product.</li></ul><p>Some of those questions gesture at something the canvas does quietly. It captures not just <em>who&apos;s</em> in your world&#x2014;builders and users&#x2014;but the gap between the state you&apos;re in and the state you want. The discipline that exposes that gap is to work the canvas right to left: start with who you want your Community Members to be and what Impact you want to have, then ask whether your current Value Propositions match the community you&apos;ve actually got. If they don&apos;t, the cells you&apos;ve written down are describing a project pointed somewhere other than the future you want. The cells that earn their keep aren&apos;t the ones describing what you do now; they&apos;re the ones that make you decide what to carry forward and what to stop.</p><h2 id="run-it-yourself">Run it yourself</h2><p>No special software, no template, nothing that has to look like ours: a canvas is just as happily done on paper, in a shared doc, on a whiteboard, or vibe-coded in an hour. The format matters less than the honesty.</p><p>Next in the series, we move from <em>who&apos;s in your world</em> to <em>how value flows through it</em>: the Ecosystem and Stakeholder Map&#x2014;including the people who aren&apos;t rooting for you.</p><hr><p><em>Mara Averick is a developer advocate at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and contributor experience lead for </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote>]]></content:encoded></item><item><title><![CDATA[What We're No Longer Seeing: AI and the Invisible Newcomer in Open Source]]></title><description><![CDATA[How AI is absorbing the visible friction that open-source communities have always relied on to see—and welcome—newcomers.]]></description><link>https://blog.stdlib.io/ai-and-the-invisible-newcomer-in-open-source/</link><guid isPermaLink="false">6a255096ed2315029621f279</guid><category><![CDATA[Developer Relations]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Sun, 07 Jun 2026 11:00:00 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/06/gen_splash.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/06/gen_splash.png" alt="What We&apos;re No Longer Seeing: AI and the Invisible Newcomer in Open Source"><p>Last winter, our team went through I-Corps training as part of the NSF&apos;s POSE&#x2014;Pathways to Enable Open-Source Ecosystems&#x2014;program. I-Corps is the National Science Foundation&apos;s customer-discovery training, and POSE adapts it for open-source projects. For us, that meant seven weeks and more than a hundred interviews with stakeholders in and around our ecosystem. (The &quot;us&quot; here is <a href="https://stdlib.io/?ref=blog.stdlib.io">stdlib</a>, an open-source standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing.)</p><p>These ecosystem-discovery interviews had one hard and fast rule: <em>you don&apos;t pitch.</em> No explaining what stdlib does, no defending decisions, no selling.</p><p>You ask, and you listen.</p><p>So that&apos;s what we did. The curriculum taught us how open-source ecosystems are supposed to be sustained&#x2014;the frameworks, the canvases, the interview discipline. The interviews taught us something nobody had put on the syllabus. Talking with maintainers, contributors, and users, the same theme kept surfacing: AI was changing how people found projects, got help, and contributed. And we weren&apos;t just hearing it in the interviews. At conferences and in hallway conversations, in blog posts and LinkedIn threads, peers who do developer relations and community work for a living were describing the same shift from their own angles.</p><p>We went to learn about our ecosystem. While we were looking, the ecosystem was changing around us.</p><p>This post is about what we were seeing. It&apos;s also about what we weren&apos;t.</p><p>For a long time, open-source communities have depended on a specific kind of visible friction. People got stuck and they showed up&#x2014;on Stack Overflow, in GitHub issues, on mailing lists, in forum threads. That first act of asking for help in public was itself a form of participation. It was the way you found the edge of someone else&apos;s community, and the way they found you.</p><p>There&apos;s an old model from Charles Vogl&apos;s <em>The Art of Community</em>&#x2014;the idea that any community has concentric rings around it. People start as visitors. They find their footing. They ask, in one way or another, <em>what am I doing here?</em> The journey from the outer ring inward&#x2014;visitor to member to elder&#x2014;isn&apos;t automatic. It requires visible pathways. It requires people willing to guide. And, crucially, it requires that the path be known to others.</p><p>That model isn&apos;t unique to Vogl, or to open source. The figure below comes from <a href="https://eric.ed.gov/?id=ED360387&amp;ref=blog.stdlib.io">a study</a> of a community most readers have no skin in: recreational scuba divers in the early 1990s. Edouard Lagache, building on <strong>legitimate peripheral participation</strong> (a term coined by Jean Lave and &#xC9;tienne Wenger), mapped the same geometry&#x2014;old-timers at the center, casual sightseers at the outermost ring, a labeled trajectory pulling inward. People become members of a community by doing low-risk things at its edges&#x2014;things that exist <em>because</em> there&apos;s a structure around them that makes them visible. Early 90s scuba diving is just an example, but the same dynamic and shape exists in open source, in sports, in fandoms, in any community you can name. The details differ, but the geometry is the same.</p><figure class="kg-card kg-image-card"><img src="https://blog.stdlib.io/content/images/2026/06/lagache1993_figure5.svg" class="kg-image" alt="What We&apos;re No Longer Seeing: AI and the Invisible Newcomer in Open Source" loading="lazy" width="900" height="580"></figure><p>What made it work in open source, structurally speaking, was friction&#x2014;visible friction. Someone got stuck, showed up, and both sides could see each other. That first public question was a form of initiation, and it was also legitimate peripheral participation in action: a low-risk, visible way of taking part from the edge. That dynamic is woven through decades of open-source community-building practice&#x2014;it&apos;s underneath <a href="https://doi.org/10.1371/journal.pcbi.1007296?ref=blog.stdlib.io">Ten simple rules for helping newcomers become contributors to open projects</a>, among others. The public question made the newcomer visible, and it created the opportunity for someone already inside to respond.</p><p>It also made the community visible to the newcomer. <em>Oh&#x2014;there&apos;s a there here. There are people. There&apos;s a way in.</em></p><p>For a while, the shift we kept hearing about was a vibe more than a finding&#x2014;something you could feel in the conversations before you could point to it on a chart. But it kept turning out to be tangible. At FOSDEM this year, David Allen, who leads developer relations at Grafana, <a href="https://fosdem.org/2026/schedule/event/KXPSTQ-the_ai_shockwave_in_open_source_communities_how_ai_is_reshaping_the_foundations_/?ref=blog.stdlib.io">showed everyone his numbers</a>, describing a moment some maintainers haven&apos;t had yet but many will.</p><p>He&apos;d gotten comfortable expecting community growth of 8 to 18 percent a quarter, almost automatically&#x2014;<em>I could fall asleep,</em> he said, <em>and the community would grow.</em> Then one quarter the number dropped 27 percent. They checked the data, ran it again, and it wasn&apos;t a measurement error: the number of people entering the community had collapsed, even though overall user growth was still going up. The mechanism wasn&apos;t mysterious, either. Organic traffic to community spaces was down roughly 30 percent, traceable to question-and-answer behavior moving to LLMs.</p><p>And it&apos;s not a one-project story. <a href="https://doi.org/10.1093/pnasnexus/pgae400?ref=blog.stdlib.io">A 2024 study</a> in <em>PNAS Nexus</em> found a clean way to isolate the effect: compare Stack Overflow activity in English (where ChatGPT was available) with Russian- and Chinese-language counterparts (where it wasn&apos;t), and with mathematics forums (where LLMs are weaker). Within six months of ChatGPT&apos;s release, English-language activity had dropped 25 percent relative to those controls&#x2014;and the authors call that a lower bound. The decline wasn&apos;t limited to beginners or to duplicate questions. Experienced and inexperienced users alike posted less.</p><p>And that was 2024. You don&apos;t need a natural experiment to know what&apos;s happened since: LLM-assisted development has gone from novelty to default, and more of the questions that used to be asked in public are answered in private.</p><p>Allen and his co-presenter, Amanda Wagner, offered a framing I keep coming back to: AI isn&apos;t the cause of this. It&apos;s an accelerant, exposing foundations that were already fragile.</p><p>Here&apos;s where the argument I want to make sharpens.</p><p>The surface loss is signal. Questions that used to surface as GitHub issues or forum threads are now answered privately. That&apos;s real, and it&apos;s measurable, and it&apos;s not nothing. But it understates what&apos;s actually happening.</p><p>When AI handles the initial friction, the newcomer gets unblocked. They get functional value. They make progress; they solve the problem. But they get it without connection&#x2014;without anyone seeing them, without a moment of initiation. This isn&apos;t inherently bad. It&apos;s just different. However, the friction that we&apos;ve always addressed as a &quot;bug&quot;&#x2014;the thing we wanted to smooth out&#x2014;was also doing work we didn&apos;t understand until it was gone.</p><p>Think about what deepens anyone&apos;s engagement with a community&#x2014;what turns getting an answer into the start of a journey: they choose it, they&apos;re making progress in it, and they feel some connection to the people in it. AI delivers choice and progress with remarkable efficiency, but it doesn&apos;t replicate connection.</p><p>And here&apos;s the part that doesn&apos;t get said enough:</p><p><strong>The blindness goes both ways.</strong></p><p>The newcomer doesn&apos;t know they&apos;re at the edge of your community. They&apos;re using your software through an AI intermediary, and they may not think of themselves as being in relationship with a project at all&#x2014;only with a tool. They don&apos;t know you exist as a community. They only know you exist as a dependency. They have no idea that they&apos;re already part of your ecosystem.</p><p>And you don&apos;t know they&apos;re there.</p><p>Vogl&apos;s inner-rings model depends on visibility in both directions. People can only be invited inward if they can be seen. They can only begin the journey if they know there&apos;s a path. When the first interaction with a project happens through an AI layer, neither condition is reliably met.</p><p>This is a different problem than the old problem of lurkers. Lurkers were quiet, but they were <em>present.</em> They were in your spaces. They could see you, even when you couldn&apos;t see them. The observer who finds your library through an AI assistant may never visit your spaces at all.</p><p>To be clear: not everyone wants to move inward, and that&apos;s fine. Vogl <a href="https://www.charlesvogl.com/articles/people-mature-inside-communities?ref=blog.stdlib.io">writes about this directly</a>&#x2014;most members of any community stay in the outer rings, and a healthy community makes room for them. Users don&apos;t owe a project anything. But open-source ecosystems aren&apos;t sustained by everyone; they&apos;re sustained by the few who do make the journey inward. And that&apos;s the real cost of the outer rings going invisible. It&apos;s not that every unseen user is a lost contributor. It&apos;s that we no longer know who&apos;s out there&#x2014;which means we no longer know whom to invite.</p><p>What&apos;s actually being lost, then, is not support traffic or page views or the other surface metrics. It&apos;s the early moments of maturation&#x2014;the activities that mark a new member, signal arrival, and begin the process of belonging. The public question used to be one of those moments, almost without anyone meaning it that way. It made someone visible, opened a door, created the conditions for response.</p><p>And we kept hearing versions of this from people working entirely different corners of the problem. Abigail Cabunoc Mayes, <a href="https://fosdem.org/2026/schedule/event/AJGB73-the_synthetic_senior_rethinking_free_software_mentorship_in_the_ai_era/?ref=blog.stdlib.io">talking about mentorship at FOSDEM</a>, put it plainly: &quot;the volume of contributions is going up, but the signal-to-noise ratio is really going down.&quot; A community can look alive by the surface metrics&#x2014;commits, PRs, downloads&#x2014;while the substrate of belonging is hollowing out underneath.</p><p>The months since haven&apos;t quieted any of this. Maintainers are sharing their experiences&#x2014;Daniel Stenberg has been chronicling <a href="https://daniel.haxx.se/blog/2026/05/26/the-pressure/?ref=blog.stdlib.io">what the AI era looks like from inside curl</a>, and Franck Nijhof recently described <a href="https://frenck.dev/open-source-was-not-ready-for-ai-speed-contributions/?ref=blog.stdlib.io">Home Assistant&apos;s version of it</a>: contributions arriving faster than anyone can review them, because &quot;contributors are being amplified, but maintainers are still the verification bottleneck.&quot; Projects across the ecosystem are rethinking their contribution policies in response. The particulars differ; the shape is the same.</p><p>And here&apos;s the uncomfortable realization underneath all of it: <em>we were relying on a friction we didn&apos;t even know we needed</em>. The playbook for building and sustaining open-source communities&#x2014;accumulated over decades by a lot of people who took the question seriously&#x2014;assumed newcomers would keep becoming visible on their own. Nobody wrote that assumption down, because nobody had to. Now that it&apos;s failing, the playbook has to change.</p><h2 id="this-is-a-design-problem-not-a-crisis">This is a design problem, not a crisis</h2><p>The instinct, when something erodes, is to mourn it or try to restore it. The more useful response is to ask: what has to be built intentionally that used to happen as a byproduct?</p><p>Everything we were learning&#x2014;from the program on one track, from our interviews and our peers on the other&#x2014;kept converging on the same few answers.</p><p>The communities that come through this in shape will be the ones oriented around <em>relationships and narrative</em>&#x2014;not tooling, not clever onboarding flows, not any one platform. The technology stack underneath a community is replaceable. What isn&apos;t replaceable is whether the people in it are in real relationship with each other and with the project, and whether the project has a story about itself that someone can find their way into. That sounds soft. It is the hard part.</p><p>A piece of that is what Allen and Wagner call <em>proof of effort.</em> When the cost of producing surface-level engagement falls&#x2014;an issue that reads as plausible, a PR that compiles, a comment that sounds informed&#x2014;the signal that someone is actually here, actually paying attention, actually committed, has to come from somewhere else. Getting prospective contributors to demonstrate investment becomes more important, not less. Not as a gatekeeping move. As a way of making real participation visible again. Communities that ask people to <em>do something on the project&apos;s terms</em>&#x2014;show up to a call, take a small responsibility, write the doc nobody wants to write&#x2014;are not being precious. They are reconstructing the legibility the old friction used to provide.</p><p>The other shift&#x2014;one we heard named, in almost the same words, by different people in different rooms&#x2014;is from <em>extractive</em> to <em>contributive</em>: communities oriented around what someone can give to the project, not just what they can get from it. That&apos;s not a new idea either. What&apos;s new is that the default has flipped. If you don&apos;t say anything, the default relationship a person now has with your project is consumption with an AI in the middle. The contributive frame has to be made explicit because the extractive one is no longer being challenged by the structure of how people find you.</p><p>The structural argument follows directly from this. If the passive onramps are narrowing&#x2014;and the evidence is now plural enough that this is no longer a hunch&#x2014;then the active ones have to be designed. If the outer ring of the community is becoming invisible, you have to go looking for the people in it; they will not show up on your dashboard. If initiation no longer happens by accident, the project has to create the conditions for it on purpose. None of this is a return to a previous state. It&apos;s a different posture toward maintenance: looking, naming, inviting, and following up are now first-order work, not extracurricular.</p><p>Which lands the section, and the post, in one specific place.</p><p>Invitation. Invitation has to come from someone already inside the community&#x2014;someone with standing, someone whose attention means something&#x2014;saying out loud to a particular person: <em>we see you, and there&apos;s a place for you here.</em> That isn&apos;t new advice. The communities-of-practice literature has been making this argument, in one form or another, for thirty years. What&apos;s new is that it used to be advice. Now it&apos;s structural. The friction that used to put newcomers in front of us is thinner. The work of putting them in front of us, on purpose, is the work.</p><h2 id="what-you-might-not-be-seeing%E2%80%94and-whats-next">What you might not be seeing&#x2014;and what&apos;s next</h2><p>So: what signals are you still relying on that may no longer be reaching you? What onramps did you assume would always be there? Whose first contact with your project this year went through a layer you can&apos;t see into&#x2014;and what would it take to find out?</p><p>In subsequent posts, I want to talk about the tools I-Corps handed us for actually looking at these questions honestly. A canvas, a map, a journey&#x2014;they aren&apos;t the answer, but they can help you take a realistic look at your ecosystem and figure out where the gaps are.</p><h2 id="sources">Sources</h2><ul><li>Allen, D., &amp; Wagner, A. V. (2026). <em>The AI Shockwave in Open Source Communities: How AI Is Reshaping the Foundations of Open Source Communities.</em> FOSDEM 2026, Brussels. <a href="https://fosdem.org/2026/schedule/event/KXPSTQ-the_ai_shockwave_in_open_source_communities_how_ai_is_reshaping_the_foundations_/?ref=blog.stdlib.io">https://fosdem.org/2026/schedule/event/KXPSTQ-the_ai_shockwave_in_open_source_communities_how_ai_is_reshaping_the_foundations_/</a></li><li>Cabunoc Mayes, A. (2026). <em>The Synthetic Senior: Rethinking Free Software Mentorship in the AI Era.</em> FOSDEM 2026, Brussels. <a href="https://fosdem.org/2026/schedule/event/AJGB73-the_synthetic_senior_rethinking_free_software_mentorship_in_the_ai_era/?ref=blog.stdlib.io">https://fosdem.org/2026/schedule/event/AJGB73-the_synthetic_senior_rethinking_free_software_mentorship_in_the_ai_era/</a></li><li>del Rio-Chanona, R. M., Laurentsyeva, N., &amp; Wachs, J. (2024). Large language models reduce public knowledge sharing on online Q&amp;A platforms. <em>PNAS Nexus</em>, 3(9): pgae400. <a href="https://doi.org/10.1093/pnasnexus/pgae400?ref=blog.stdlib.io">https://doi.org/10.1093/pnasnexus/pgae400</a></li><li>Lagache, E. (1993). <em>&quot;Diving&quot; into Communities of Practice: Examining Learning as Legitimate Peripheral Participation in an Everyday Setting.</em> Paper presented at the American Educational Research Association annual meeting, Atlanta, GA. ERIC ED 360 387. <a href="https://eric.ed.gov/?id=ED360387&amp;ref=blog.stdlib.io">https://eric.ed.gov/?id=ED360387</a></li><li>Lave, J., &amp; Wenger, E. (1991). <em>Situated Learning: Legitimate Peripheral Participation.</em> Cambridge University Press.</li><li>Sholler, D., Steinmacher, I., Ford, D., Averick, M., Hoye, M., &amp; Wilson, G. (2019). Ten simple rules for helping newcomers become contributors to open projects. <em>PLOS Computational Biology</em>, 15(9): e1007296. <a href="https://doi.org/10.1371/journal.pcbi.1007296?ref=blog.stdlib.io">https://doi.org/10.1371/journal.pcbi.1007296</a></li><li>Vogl, C. H. (2025). <em>The Art of Community: 7 Principles for Belonging</em> (2nd ed.). Berrett-Koehler.</li></ul><hr><p><em>Mara Averick is a developer advocate at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and contributor experience lead for </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p><h2 id="acknowledgments">Acknowledgments</h2><p>This work was supported in part by the National Science Foundation under <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2449410&amp;HistoricalAwards=false&amp;ref=blog.stdlib.io">Award No. 2449410</a>.</p><blockquote>Disclaimer: Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.</blockquote>]]></content:encoded></item><item><title><![CDATA[GSoC 2026 Selected Projects]]></title><description><![CDATA[We're thrilled to share that stdlib will have five contributors participating in Google Summer of Code 2026.]]></description><link>https://blog.stdlib.io/gsoc-2026-selected-projects/</link><guid isPermaLink="false">69fea6aaed2315029621f20f</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[Athan Reines]]></dc:creator><pubDate>Sat, 09 May 2026 03:17:50 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/05/gen_splash-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/05/gen_splash-1.png" alt="GSoC 2026 Selected Projects"><p>We&apos;re excited to share that <a href="https://summerofcode.withgoogle.com/?ref=blog.stdlib.io">Google Summer of Code 2026</a> is officially underway and that stdlib has been awarded five contributor slots for this year&apos;s program.</p><p>This is our third year participating in GSoC, and every year the program has gotten bigger, more competitive, and more energizing for the project.</p><p>What continues to stand out most is not just the number of proposals we receive, but the level of engagement contributors bring <em>before</em> applications even open. Increasingly, contributors are showing up months in advance: opening pull requests, participating in discussions, helping with reviews, fixing bugs, improving documentation, and steadily becoming part of the community long before proposal season begins.</p><p>And that matters.</p><p>Open source is not built over the course of a single summer. It is built through consistency, trust, curiosity, and sustained collaboration over time. GSoC works best when it amplifies an existing trajectory rather than starting from zero.</p><p>This year&apos;s application season was the most competitive we&apos;ve seen so far.</p><p>From January 1 through April 21 of this year, prospective GSoC contributors were busy ramping up on stdlib&apos;s development practices, refining their proposals, and contributing across the project. During that time, the stdlib community:</p><ul><li>opened more than 2,000 PRs, with 1,452 of those being successfully merged.</li><li>added 2,209 commits and 146 new packages.</li><li>welcomed contributions from 89 different contributors.</li></ul><p>During the official proposal period alone (February 19 &#x2013; April 21), contributors opened 1,250 pull requests and authored 1,421 commits across the project.</p><p>In total, we received <strong>75 proposals</strong> for just <strong>5 slots</strong>.</p><p>That level of participation says a lot about the momentum behind scientific computing on the web and about the community that continues to grow around stdlib.</p><h2 id="the-2026-cohort">The 2026 Cohort</h2><p>This year&apos;s accepted projects span numerical computing, machine learning, visualization, and low-level linear algebra infrastructure, all areas which are foundational to stdlib&apos;s long-term vision for scientific computing on the web.</p><p>Over the next several months, contributors will be working closely with mentors across the project, participating in design discussions, iterating on implementations, writing documentation, and helping shape the future direction of stdlib.</p><p>One thing we emphasize heavily within stdlib is that open source is not just about writing code. Good engineering requires communication, design thinking, documentation, review discipline, testing rigor, and an ability to collaborate effectively with others. GSoC gives contributors exposure to all of those dimensions.</p><p>With that, on to the projects!</p><h3 id="blas-bindings-and-implementations-for-linear-algebra">BLAS Bindings and Implementations for Linear Algebra</h3><p><strong>Contributor</strong>: <a href="https://github.com/MeKaustubh07?ref=blog.stdlib.io">Kaustubh Patange</a></p><p>This <a href="https://summerofcode.withgoogle.com/programs/2026/projects/Mh2Oa6l1?ref=blog.stdlib.io">project</a> focuses on expanding stdlib&apos;s BLAS support by adding missing Level 2 and 3 BLAS routines. The work continues stdlib&apos;s broader effort to bring high-performance numerical computing primitives to the JavaScript ecosystem while maintaining API consistency and portability across runtimes.</p><p>More broadly, the project will strengthen one of the most important foundational layers for scientific computing: fast and reliable linear algebra operations.</p><h3 id="batch-machine-learning-algorithms-in-javascript-and-c">Batch Machine Learning Algorithms in JavaScript and C</h3><p><strong>Contributor</strong>: <a href="https://github.com/nakul-krishnakumar?ref=blog.stdlib.io">Nakul Krishnakumar</a></p><p>This <a href="https://summerofcode.withgoogle.com/programs/2026/projects/UpnxnHuL?ref=blog.stdlib.io">project</a> aims to introduce a new set of foundational machine learning algorithms to stdlib, implemented in both JavaScript and C. The focus is on building reusable low-level primitives which can serve as the basis for a broader machine learning ecosystem within stdlib over time.</p><p>Machine learning infrastructure on the web is still relatively immature compared to other ecosystems. One of stdlib&apos;s goals is to help close that gap by providing robust, modular, and composable numerical tooling that works across Node.js, browsers, edge runtimes, and beyond.</p><h3 id="singular-value-decomposition-svd-via-lapack">Singular Value Decomposition (SVD) via LAPACK</h3><p><strong>Contributor</strong>: <a href="https://github.com/prajjwalbajpai?ref=blog.stdlib.io">Prajjwal Bajpai</a></p><p>This <a href="https://summerofcode.withgoogle.com/programs/2026/projects/UUCgNDEW?ref=blog.stdlib.io">project</a> will add LAPACK bindings and JavaScript implementations for singular value decomposition (SVD), centered around LAPACK&apos;s <code>dgesvd</code> routine.</p><p>SVD is one of the most important algorithms in numerical linear algebra and underpins a wide range of applications, including dimensionality reduction, least-squares optimization, signal processing, recommendation systems, and machine learning.</p><p>Adding robust SVD support will significantly expand stdlib&apos;s growing linear algebra capabilities and move the project closer toward providing a comprehensive numerical computing stack for the web.</p><h3 id="linear-system-solvers-and-factorization-workflows">Linear System Solvers and Factorization Workflows</h3><p><strong>Contributor</strong>: <a href="https://github.com/iampratik13?ref=blog.stdlib.io">Pratik Bhagwat</a></p><p>This <a href="https://summerofcode.withgoogle.com/programs/2026/projects/sJ7nndHz?ref=blog.stdlib.io">project</a> focuses on enabling factorization-to-solution workflows within stdlib by integrating matrix factorizations and linear system solvers into a more cohesive numerical linear algebra pipeline.</p><p>In practice, scientific computing is rarely about isolated kernels. Real-world workflows often involve composing lower-level primitives into larger computational pipelines. This project will help bridge that gap by improving interoperability between routines and strengthening stdlib&apos;s higher-level numerical computing ergonomics.</p><h3 id="plotting-infrastructure-and-chart-creation">Plotting Infrastructure and Chart Creation</h3><p><strong>Contributor</strong>: <a href="https://github.com/Sachinn-64?ref=blog.stdlib.io">Sachin Pangal</a></p><p>This <a href="https://summerofcode.withgoogle.com/programs/2026/projects/AOnAAohn?ref=blog.stdlib.io">project</a> will extend stdlib&apos;s plotting infrastructure by implementing missing components needed for end-to-end chart generation using Vega.</p><p>Visualization is a critical part of scientific computing workflows, yet the JavaScript ecosystem still lacks cohesive, low-level scientific visualization tooling designed around composability and modularity. This work will help move stdlib toward a more complete data analysis and visualization stack capable of supporting exploratory analysis, diagnostics, dashboards, and educational tooling directly in the browser and in server-side runtimes such as Node.js.</p><h2 id="more-than-a-summer-program">More Than a Summer Program</h2><p>One of the most rewarding aspects of GSoC has been seeing contributors continue participating well after the program ends.</p><p>Several former GSoC contributors are still active members of the stdlib community today, continuing to review code, mentor newer contributors, and help drive development across the project. That long-term continuity is enormously valuable and is ultimately what makes programs such as GSoC successful.</p><p>For stdlib specifically, GSoC has also helped accelerate an important broader goal: building a sustainable ecosystem for scientific computing in JavaScript and bringing more contributors into that ecosystem.</p><p>The web platform has become one of the most important computing environments in the world. Scientific computing tools should exist there as first-class citizens.</p><p>That means performant numerical primitives. It means robust infrastructure. It means approachable tooling. It means strong documentation. And it means building a healthy contributor community capable of sustaining all of that over the long term.</p><p>Programs like GSoC help make that possible.</p><h2 id="thank-you">Thank You</h2><p>A huge thank you to everyone who submitted a proposal this year.</p><p>We know how much time and effort goes into preparing applications, contributing beforehand, engaging with mentors, and refining project ideas. The selection process was very difficult this year, and there were many strong proposals we simply did not have enough slots to support.</p><p>We also want to thank all of the mentors and community members who continue investing time into reviewing pull requests, answering questions, helping contributors onboard, and supporting the project day to day. Open source communities only work because people choose to show up for one another.</p><p>We&apos;re excited to get started and are looking forward to seeing what this year&apos;s contributors build.</p><hr><p><em>Athan Reines is a software engineer at </em><a href="https://quansight.com/?ref=blog.stdlib.io"><em>Quansight</em></a><em> and core developer of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[Zen of stdlib]]></title><description><![CDATA[A philosophy of simplicity, modularity, consistency, and craft.]]></description><link>https://blog.stdlib.io/zen-of-stdlib/</link><guid isPermaLink="false">69fe80c3ed2315029621f1c3</guid><category><![CDATA[Engineering]]></category><dc:creator><![CDATA[Athan Reines]]></dc:creator><pubDate>Sat, 09 May 2026 00:38:17 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2026/05/gen_splash.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2026/05/gen_splash.png" alt="Zen of stdlib"><p>Over the past several years, stdlib has grown from a small collection of utilities into a large, highly modular system for scientific computing in JavaScript and on the web. Along the way, we&apos;ve made thousands of small decisions about APIs, naming, performance, package boundaries, and implementation strategies.</p><p>Individually, those decisions may seem minor. Collectively, they define the character of the project.</p><p>As the project has grown, it&apos;s become increasingly important to make those underlying principles explicit not just for maintainers, but for contributors and users who want to understand how and why stdlib is the way it is.</p><p>Today, we&apos;re introducing the <a href="https://github.com/stdlib-js/stdlib/blob/cfecd68a37a2593d143fe35e3bd1e2b6de31ffbf/docs/contributing/zen_of_stdlib.md?ref=blog.stdlib.io" rel="noreferrer"><strong>Zen of stdlib</strong></a>: a set of guiding principles that capture the philosophy behind the project.</p><h2 id="why-a-zen">Why a &quot;Zen&quot;?</h2><p>This is not a style guide.</p><p>It&apos;s not a checklist.</p><p>And it&apos;s not meant to be followed dogmatically.</p><p>Instead, the Zen is a distillation of experience: what has worked, what hasn&apos;t, and what tends to scale as a codebase and community grow. It exists to guide decisions, especially in ambiguous situations where there is no obviously &quot;correct&quot; answer.</p><p>If you&apos;ve ever asked questions like:</p><ul><li>Should this be a new package or part of an existing one?</li><li>Is this API too general?</li><li>Should we add another option or compose existing functionality?</li><li>Is this abstraction worth it?</li></ul><p>The Zen is meant to help answer those questions.</p><h2 id="the-zen-of-stdlib">The Zen of stdlib</h2><pre><code class="language-text">Do one thing. Do it well.
Embrace radical modularity.
Favor composition over configuration.
Stability is a feature.

Make it obvious and predictable.
Don&apos;t be clever.

Complexity kills.
Push complexity up the stack.

If it&apos;s hard to explain, it&apos;s a bad idea.
If it&apos;s hard to test, it&apos;s a bad design.

Failure should be easy to diagnose.

Value consistency above all else.
Except when correctness, safety, or clarity demands otherwise.

Write it like C.
Be explicit. Avoid polymorphism by default.

Automate where it scales; stop where it obscures.

Code is read more than it is written.
Be kind to your future self.

Code is craft.
Tend to the garden.

Mistakes are infectious.
Fix them early.

Simple is beautiful.
</code></pre><h2 id="what-this-means-in-practice">What this means in practice</h2><p>A few themes show up repeatedly throughout stdlib.</p><h3 id="radical-modularity">Radical modularity</h3><p>If something can stand on its own, it should.</p><p>stdlib is intentionally composed of many small packages rather than a few large ones. This enables reuse, makes testing easier, and allows consumers to include only what they need. It also forces discipline, as each package must have a clear purpose and boundary.</p><h3 id="composition-over-configuration">Composition over configuration</h3><p>We prefer simple building blocks over highly configurable interfaces.</p><p>Instead of adding more flags, options, and modes, we aim to provide small primitives that can be composed. This keeps individual APIs predictable and avoids combinatorial complexity.</p><h3 id="pushing-complexity-up-the-stack">Pushing complexity up the stack</h3><p>Lower-level APIs should be simple, predictable, and easy to reason about.</p><p>More complex behavior, such as branching logic, multiple modes of operation, and orchestration, belongs in higher-level utilities built on top of those primitives. This separation is critical for both performance and maintainability.</p><h3 id="predictability-and-consistency">Predictability and consistency</h3><p>Users should not have to guess what an API does.</p><p>Naming conventions, argument ordering, and error behavior should be consistent across the entire project. Consistency reduces cognitive load and makes the system easier to learn and use.</p><h3 id="performance-by-design">Performance by design</h3><p>&quot;Write it like C&quot; is less about language and more about mindset.</p><p>We favor predictable performance characteristics, monomorphic code paths, and explicit behavior. Hidden allocations, excessive polymorphism, and implicit work tend to introduce both performance and debugging challenges.</p><h3 id="maintainability-as-a-first-class-concern">Maintainability as a first-class concern</h3><p>Code is read far more often than it is written.</p><p>That reality drives many of the principles in the Zen: clarity over cleverness, simplicity over abstraction, and documentation that explains not just <em>what</em> the code does, but <em>why</em>.</p><h2 id="a-living-document">A living document</h2><p>The Zen of stdlib is not fixed.</p><p>As the project evolves, so will our understanding of what works and what doesn&apos;t. The Zen may change over time, but changes should be rare, deliberate, and grounded in experience.</p><h2 id="for-contributors">For contributors</h2><p>If you&apos;re contributing to stdlib, the Zen is a useful reference point when designing APIs or reviewing code.</p><p>It won&apos;t answer every question, but it should help you reason about trade-offs and make decisions that align with the broader direction of the project.</p><p>When in doubt: prefer <strong>simplicity</strong>, <strong>clarity</strong>, and <strong>consistency</strong>.</p><h2 id="closing">Closing</h2><p>stdlib is an ongoing experiment in what scientific computing in JavaScript and on the web looks like when built around strong principles.</p><p>The Zen is an attempt to capture those principles so that the project can continue to grow without losing what makes it coherent.</p><p>As always, feedback is welcome.</p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[Connect with the stdlib community on Zulip]]></title><description><![CDATA[Announcing the launch of stdlib's new Zulip chat community]]></description><link>https://blog.stdlib.io/announcing-zulip/</link><guid isPermaLink="false">69422db0ed2315029621f198</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[Mara Averick]]></dc:creator><pubDate>Wed, 17 Dec 2025 05:32:06 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1604881988758-f76ad2f7aac1?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvbnZlcnNhdGlvbnxlbnwwfHx8fDE3NjU5NDQ3NTl8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1604881988758-f76ad2f7aac1?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvbnZlcnNhdGlvbnxlbnwwfHx8fDE3NjU5NDQ3NTl8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Connect with the stdlib community on Zulip"><p>As the stdlib community continues to grow and evolve, so has our need for new ways to connect and collaborate (see, for example, our <a href="https://blog.stdlib.io/new-ways-to-engage-with-the-stdlib-community">announcement of office hours and a public events calendar</a>). While Gitter&apos;s simple, single-channel interface worked well in the early days, it no longer scales with the range of conversations happening around the project. Today we&apos;re excited to announce our new <a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io">Zulip chat</a>, which provides a more full-featured, structured, and searchable space for us to interact.</p><h2 id="why-zulip">Why Zulip?</h2><p><a href="https://zulip.com/?ref=blog.stdlib.io">Zulip</a> is open source and generously <a href="https://zulip.com/for/open-source?ref=blog.stdlib.io">supports open-source projects</a> like ours with a free cloud plan. Its channel-and-topic model makes it easier to keep discussions focused, follow ongoing threads, and resurface past knowledge through powerful <a href="https://zulip.com/help/search-for-messages?ref=blog.stdlib.io#search-filters">search features</a>.</p><p>Anyone can browse the web-public channels of <a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io">stdlib&apos;s Zulip</a> without an account, and you can sign up at any time to join the conversation.</p><h2 id="join-and-get-started">Join and get started</h2><p>The <a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io"><strong>stdlib Zulip chat</strong></a> is open to all. A welcome bot will greet you when you first join and share some tips specific to stdlib about how to participate effectively. If you&apos;re new to Zulip, their <a href="https://zulip.com/help/getting-started-with-zulip?ref=blog.stdlib.io">getting started guide</a> is an invaluable resource. If you&apos;re already familiar with applications such as Slack or Discord, much of the experience will be familiar.</p><p>We encourage you to come say hello in the <a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io#narrow/channel/546733-introductions"><strong>#introductions</strong></a> channel and take some time to explore other channels and topics that may be of interest to you. If you have any questions about Zulip itself, we&apos;ve got a channel for that too (<a href="https://stdlib.zulipchat.com/?ref=blog.stdlib.io#narrow/channel/546662-zulip"><strong>#zulip</strong></a>).</p><p>The stdlib team is active in the chat, and public messages are the best way to get timely help&#x2014;no need for routine <strong>@-mentions</strong>. Asking questions in public is the fastest way to get a response, as more people can help, <em>plus</em> it&apos;s likely that someone else will benefit from finding out the answer to your question. The stdlib <a href="https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md?ref=blog.stdlib.io">Code of Conduct</a> applies to all community spaces, including stdlib&apos;s Zulip. Should you encounter an issue, Zulip&apos;s <a href="https://zulip.com/help/report-a-message?ref=blog.stdlib.io">reporting tools</a> and our moderation team are available.</p><h2 id="see-you-there">See you there!</h2><p>We&apos;re looking forward to seeing you in the stdlib Zulip instance! We welcome questions and suggestions as we continue shaping a space that is useful, inclusive, and genuinely supportive for everyone who wants to learn, build, or contribute.</p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">financially supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[Using AI in the development of stdlib]]></title><description><![CDATA[A reflection on stdlib's participation in the 2025 METR study on AI's impact on open-source developer productivity.]]></description><link>https://blog.stdlib.io/reflection-on-the-metr-study-2025/</link><guid isPermaLink="false">687949d7ed2315029621f14b</guid><category><![CDATA[Engineering]]></category><dc:creator><![CDATA[Philipp Burckhardt]]></dc:creator><pubDate>Thu, 17 Jul 2025 19:13:54 GMT</pubDate><media:content url="https://blog.stdlib.io/content/images/2025/07/gen_splash_1120x670.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.stdlib.io/content/images/2025/07/gen_splash_1120x670.png" alt="Using AI in the development of stdlib"><p>I read the results of the recent METR study on <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/?ref=blog.stdlib.io">&quot;Impact of Early-2025 AI on Experienced Open-Source Developer Productivity&quot;</a> with great interest for two reasons. Firstly, I have been an early adopter of LLM tools. In 2020, I was lucky enough to get access to the private beta of the OpenAI API from then CTO Greg Brockman and explored the use of AI for education at Carnegie Mellon University. Secondly, because <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> participated in the METR study, I was personally involved and contributed by working on randomized <a href="https://github.com/stdlib-js/metr-issue-tracker?ref=blog.stdlib.io">issues</a> over several months, being allowed to use AI for some tasks and forbidden for others.</p><p>Given that <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a>&apos;s involvement is central to my perspective, it&apos;s worth providing some context on the project. stdlib is a comprehensive open-source standard library for JavaScript and Node.js, with a specific and ambitious goal: to be the fundamental library for numerical and scientific computing on the web. It is a large-scale project with well over 5 million source lines of JavaScript, C, Fortran, and WebAssembly, and composed of thousands of independently consumable packages, bringing the rigor of high-performance mathematics, statistics, and machine learning to the JavaScript ecosystem. Think of it as a foundational layer for data-intensive applications similar to the roles NumPy and SciPy serve in the Python ecosystem. In short, stdlib isn&apos;t your average JavaScript project.</p><h2 id="a-word-of-thanks">A Word of Thanks</h2><p>Before diving into my reflection, I want to take the opportunity to thank the METR team and especially Nate Rush for giving stdlib the chance to participate in this study with two core stdlib developers, <a href="https://github.com/headlessNode?ref=blog.stdlib.io">Muhammad Haris</a> and <a href="https://github.com/Planeshifter?ref=blog.stdlib.io">myself</a>. It was a great experience to work with the METR team, and I am eager to see any future studies they will conduct. It is my conviction that, with the entire tech industry being gripped by an AI gold rush, it is incredibly valuable to have a non-profit research institute like METR conduct studies that cut through the noise with actual data.</p><h2 id="the-slowdown">The Slowdown</h2><p>The results of the METR study are surprising, clashing with some previously published and very optimistic study results on the impact of generative AI (e.g., see GitHub and Accenture&apos;s <a href="https://github.blog/news-insights/research/research-quantifying-github-copilots-impact-in-the-enterprise-with-accenture/?ref=blog.stdlib.io#:~:text=Since%20bringing%20GitHub%20Copilot%20to,world%2C%20large%20engineering%20organizations">2023 study on the impact of Copilot on developer productivity</a>). Citing from the Core Result section of the <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/?ref=blog.stdlib.io">METR study page</a>:</p><blockquote>When developers are allowed to use AI tools, they take 19% longer to complete issues&#x2014;a significant slowdown that goes against developer beliefs and expert forecasts. This gap between perception and reality is striking: developers expected AI to speed them up by 24%, and even after experiencing the slowdown, they still believed AI had sped them up by 20%.</blockquote><p>Rather predictably, the results have led to a lot of discussion on <a href="https://news.ycombinator.com/item?id=44522772&amp;ref=blog.stdlib.io">Hacker News</a> and other social channels, with parties on both sides lining up with their pitchforks.</p><h2 id="the-perception-gap">The Perception Gap</h2><p>I am part of the group of developers who estimated that they were sped up 20%-30% during the study&apos;s exit interview. While I like to believe that my productivity didn&apos;t suffer while using AI for my tasks, it&apos;s not unlikely that it might not have helped me as much as I anticipated or maybe even hampered my efforts.</p><p>But how can that be? Daily, we are reading about how AI is already revolutionizing the workplace or making software engineers redundant, with companies like Salesforce <a href="https://www.theregister.com/2025/02/27/salesforce_misses_revenue_guidance/?ref=blog.stdlib.io">announcing</a> that they won&apos;t be hiring for software engineering positions anymore or online lender Klarna <a href="https://www.forbes.com/sites/quickerbettertech/2024/03/13/klarnas-new-ai-tool-does-the-work-of-700-customer-service-reps/?ref=blog.stdlib.io">announcing</a> that they were shuttering their entire human customer support in favor of AI.</p><p>Many of these stories have turned out to be more hyperbole than reality. Klarna <a href="https://www.independent.co.uk/news/business/klarna-ceo-sebastian-siemiatkowski-ai-job-cuts-hiring-b2755580.html?ref=blog.stdlib.io">still has</a> human support, and Salesforce still has many engineering <a href="https://careers.salesforce.com/en/jobs/?search=engineer&amp;pagesize=20&amp;ref=blog.stdlib.io#results">job listings</a>. Sadly, some of these stories appear influenced by ulterior motives, such as Klarna&apos;s strategic positioning as an &quot;AI-native&quot; company to capture premium valuations ahead of its IPO amid the current AI wave.</p><p>However, I have been using AI tools daily for the past three years, both at work and outside, and find them immensely useful. How do I square these benefits with the study results?</p><h2 id="on-study-design">On Study Design</h2><p>When confronted with results that go counter to one&apos;s expectations, it is a natural instinct to try to attack the study and identify holes to explain away the result. For example, one could point to the small sample size of 16 developers. There is also the argument that the study was conducted in a very specific context, with experienced developers working on projects they are intimately familiar with.</p><p>There might also have been a subtle selection effect in the tasks themselves: since project maintainers proposed their own task lists, it is possible that those more experienced with AI subconsciously selected issues they believed were more amenable to an agentic workflow. One could also argue that the developers were subject to the <a href="https://en.wikipedia.org/wiki/Hawthorne_effect?ref=blog.stdlib.io">Hawthorne effect</a>, altering their behavior simply because they knew they were being video-recorded, perhaps over-relying on the AI tools for the sake of the experiment.</p><p>Finally, and perhaps most importantly, the experimental setup of requiring screen recordings and active time tracking for a single task enforced a synchronous workflow. This effectively locked developers into what I call &quot;supervision mode&quot;, where they had to watch the agent work rather than being free to context-switch to another problem.</p><p>Some of these critiques, particularly the enforced &quot;supervision&quot; workflow, could directly contribute to the observed slowdown. But others, such as selecting &quot;AI-friendly&quot; tasks or over-relying on the tool to impress researchers, should have biased the results toward a speedup. This makes the final outcome even more notable. The direction of various potential biases is ambiguous at best, which is why we must look at the study&apos;s core design.</p><p>As a randomized control trial, the study follows the gold standard experimental design for detecting causality. By randomizing individual tasks to &quot;AI-allowed&quot; or &quot;AI-disallowed&quot;, the study isolates the effect of AI tooling. Instead of comparing one group of developers against a control group (where differences in skill could skew the results), it compares each developer against themselves. This &quot;within-subjects&quot; design controls for individual characteristics, from typing speed to experience with the project. With such a study design, results are harder to write off as mere statistical noise, even with a smaller sample size.</p><p>Crucially, the tasks were defined before this randomization. This avoids a common pitfall where AI might simply produce more verbose code or encourage developers to break tasks into smaller pull requests, which can inflate some productivity metrics without representing more work getting done.</p><p>16 developers from several open-source projects might not sound like much, but, in total, we completed 246 tasks. To give a sense of the work <a href="https://github.com/stdlib-js/metr-issue-tracker/issues?q=sort%3Aupdated-desc+is%3Aissue&amp;ref=blog.stdlib.io">involved</a>, the tasks Haris and I worked on were not trivial, while still being hand scoped to be completed in a few hours or less. They were a mix of core feature development (such as adding new array, string, and BLAS functions), creating custom ESLint rules to enforce project-specific coding standards, enhancing our CI/CD pipelines with new automation, and fixing bugs from our issue tracker.</p><p>And while a single developer&apos;s performance on one task is likely correlated with their performance on another and the precision of the estimates thus larger than otherwise, it is quite notable that the effect was in the opposite direction from what economists, ML experts, and the developers themselves predicted (with the former two groups being more in the range of a 40% speedup). Moreover, the effect is quite large in magnitude. A quick back-of-the-envelope calculation reveals that if the true effect were a 40% speedup, the probability of observing a result this far in the opposite direction is astronomically low.</p><p>In light of this, I have no reason to doubt the internal validity of the study and would venture that the effect measured is real within the context of the experiment. If one believed the chatter on social media and the hype merchants who two years ago were all shilling cryptocurrency (and maybe still are!) but have meanwhile all switched over to extolling the amazing speedup AI offers, then increases of 100%, 5x, or even 10x should have been in the cards. But this is definitively not what the study observed.</p><h2 id="embracing-agentic-development">Embracing Agentic Development</h2><p>The more important consideration for squaring my own experience with these results is external validity: how generalizable are the study&apos;s findings? The paper is a great read and touches on many possible criticisms and threats to external validity, and I won&apos;t belabor any of the points raised therein.</p><p>Instead, I will solely focus on my experience as a study participant and how I have been leveraging AI with success. I will also share my own hypotheses for why the performance of the developers in this sample was overall negatively affected by the use of AI.</p><p>To give some context, my main way of incorporating LLMs into my work before participating in this study was twofold. As something of an early adopter, I had used GitHub Copilot for auto-completion and inline suggestions and made heavy use of ChatGPT and Anthropic Claude web apps by assembling relevant context, writing detailed prompts, and copying results back into my editor. Tools such as <a href="https://repomix.com/?ref=blog.stdlib.io" rel="noreferrer">Repomix</a> helped streamline the process of incorporating LLMs into my daily development workflow. This general approach allowed me to review changes quickly, iterate on them by asking questions, and have the LLM make follow-up edits directly in a chat interface.</p><p>The METR study subsequently provided an excuse for me to delve into agentic programming and make Cursor an integral part of my workflow. I had used it briefly some time before but didn&apos;t find the AI-generated results compelling enough to let it loose on any codebase I was working on. But Claude Sonnet 3.7 had come out, which is still one of the most powerful models for coding tasks. Due to some very encouraging results during early testing, I was eager to put it to work on a backlog of tooling that we wanted to build for stdlib, alongside various refactoring and bug fixes.</p><p>One of my first impressions with Cursor this time around was the underlying LLM&apos;s rather impressive ability to follow the very specific coding standards and conventions of the project and, when placed in agent mode, to automatically and reliably fix lint errors and attempt to iteratively resolve errors in unit tests. This felt like another step change in capabilities, just like when OpenAI released GPT-3 Davinci in June 2020, which made a lot of use cases suddenly feasible that before would break down in any realistic scenario.</p><p>While I no longer use Cursor and have meanwhile switched to Claude Code (more on that later), I found Cursor straightforward to use, especially given that it is a fork of VSCode, which has been my IDE of choice for many years. I heavily doubt that inexperience with Cursor, which I shared with roughly a half of the developers in the study, played a major role in the results. While I didn&apos;t have an extensive <code>.cursorrules</code> setup (which has since been deprecated in favor of <a href="https://docs.cursor.com/context/rules?ref=blog.stdlib.io#project-rules">project rules</a>), I did add basic instructions and context about the project and made sure to index the stdlib codebase. Aside from that, further customization was neither possible nor necessary, as the Cursor Agent was able to automatically pull in other files, look up function call signatures, and perform other operations for assembling context.</p><p>My experience of Cursor was largely positive during the study. As an example, I ended up working on several Bash scripts for our CI/CD pipeline, and Cursor definitely sped up my development workflow by not having to look up the man page of <code>jq</code> for the eleventh time given that I only use this command-line tool for manipulating JSON once in a blue moon. With the AI agent&apos;s help, I could quickly generate a function like this one to check if a GitHub issue has a specific label:</p><pre><code class="language-bash"># Check if an issue has the &quot;Tracking Issue&quot; label.
#
# $1 - Issue number
is_tracking_issue() {
    local issue_number=&quot;$1&quot;
    local response

    debug_log &quot;Checking if issue #${issue_number} is a tracking issue&quot;
    # Get the issue:
    if ! response=$(github_api &quot;GET&quot; &quot;/repos/${repo_owner}/${repo_name}/issues/${issue_number}&quot;); then
        echo &quot;Warning: Failed to fetch issue #${issue_number}&quot; &gt;&amp;2
        return 1
    fi

    # ...

    # Check if the issue has the &quot;Tracking Issue&quot; label:
    if echo &quot;$response&quot; | jq -r &apos;.labels[].name&apos; 2&gt;/dev/null | grep -q &quot;Tracking Issue&quot;; then
        debug_log &quot;Issue #${issue_number} is a tracking issue&quot;
        return 0
    else
        debug_log &quot;Issue #${issue_number} is not a tracking issue&quot;
        return 1
    fi
}
</code></pre><p>The agent correctly assembled the <code>jq -r &apos;.labels[].name&apos;</code> filter to extract the label names from the JSON response&#x2014;something that would have sent me to a documentation page for a few minutes. While a small speed bump, these moments add up. The AI handled the rote task of recalling obscure syntax, letting me focus on the actual logic.</p><p>My first takeaway is this: current LLMs are very powerful for tasks in domains that you are not intimately familiar with, allowing you to move much more quickly. Agentic tools such as Cursor and Claude Code are also very helpful to quickly navigate and learn your way around a large codebase, allowing you to ask questions and explore the codebase in a natural way. Leveraging &quot;deep research&quot; provides another means to more exhaustively explore a problem space in a way that the search engines of old simply cannot match.</p><p>On the other hand, some tasks were very frustrating. For example, the Cursor agent wrote one ESLint rule almost fully in one shot, but for another one, the Cursor agent was running in circles and unable to figure out the correct algorithm. Trying to prompt it to fix the bug was unsuccessful multiple times. It would have been better to not fall prey to the <a href="https://en.wikipedia.org/wiki/Sunk_cost?ref=blog.stdlib.io">sunk cost fallacy</a> and instead throw away the code and then either give the agent another shot or write it myself.</p><blockquote>Cursor does have a neat feature of breakpoints which allow you to stop the agent at any time and revert to a prior state, something I wholeheartedly recommend using. It is a great way to avoid getting stuck in a loop of the agent trying to fix a bug that it cannot figure out.</blockquote><p>I freely admit that I may have been a bit overeager about using AI for all of the AI-enabled tasks, partly due to my desire to learn to use Cursor productively but also due to my general amazement of what these new technologies unlock. However, maybe the METR study suggests that the question of whether a task can be more efficiently completed by AI, or whether one would be better off completing it by hand, is far from settled.</p><h2 id="the-blank-slate-problem">The Blank Slate Problem</h2><p>Aside from occasional inefficiencies and outright mistakes in the generated code, coding agents do not have access to all the implicit knowledge and conventions of a large, mature project, which often might not be written down. In <a href="https://johnwhiles.com/posts/mental-models-vs-ai-tools?ref=blog.stdlib.io">his reflections</a> on the study, John Whiles identifies a core conflict: an expert engineer&apos;s primary value isn&apos;t just writing code; it&apos;s holding a complete, evolving mental model of the entire system in their head. The agent does not have such a mental model. Every interaction starts from a blank slate.</p><p>It is possible that some of this can be mitigated with better, more targeted instructions. As usual, there is no free lunch. One has to actively invest in making one&apos;s codebase more accessible to coding agents. And more generally, memory and learning is an unsolved problem with transformer-based LLMs, and changing that will likely require fundamental architectural advancements.</p><p>The necessity of auditing the agent&apos;s code for mistakes created two major sources of friction: the cognitive drain of &apos;babysitting&apos; the AI and the time spent waiting for and reviewing its output. For every minute the agent spent running in circles on that ESLint rule, I was blocked, my attention monopolized by the need to supervise its flawed process. This synchronous, blocking workflow is exhausting and inefficient. It&apos;s the digital equivalent of shoulder-surfing an overconfident junior developer who has memorized everything there is to know about programming but cannot be trusted and who will make subtle mistakes that are hard to spot.</p><p>My advice: stay in the driver&apos;s seat during such pair programming and use the AI as a sparring partner to bounce ideas back and forth instead of yielding agency.</p><h2 id="delegate-dont-supervise">Delegate, Don&apos;t Supervise</h2><p>Partly based on my experiences in the study, my workflow has evolved, and I have subsequently switched to using Anthropic&apos;s Claude Code. This has changed my interaction model from synchronous supervision to asynchronous delegation. I can now define a complex task via Claude Code&apos;s planning mode and then have the agent work on the task in the background. I can then turn my full attention elsewhere, be it attending a meeting, reviewing a colleague&apos;s code, or simply thinking through the next problem without interruption. Claude&apos;s work happens in parallel and is not a blocker to my own. The cognitive cost of babysitting is replaced by the much lower cost of reviewing a completed proposal later; if it didn&apos;t work out, I might just throw away the code and have the model try again, instead of engaging in a fruitless back and forth.</p><p>Claude Sonnet 4 and Opus 4 were not released at the time the METR study was conducted, and, while they mark another improvement, especially with regard to tool use by the model, the dynamics haven&apos;t fundamentally changed. The models still make mistakes and do not always implement things in an optimal or sound way, but they are now much better at following instructions and can work uninterrupted for longer periods of time.</p><p>At least for me, in contrast to those who frame coding agents as mere &quot;stochastic parrots&quot;, I find myself absolutely amazed that, despite its warts and hiccups, we have now a technology that, given a set of instructions, is able to generate a fully-formed pull request that correctly implements logic, adheres to style guidelines, and has a passing test suite. And, in the best cases, this can happen without any human intervention.</p><h2 id="the-first-80-percent">The First 80 Percent</h2><p>We still need to reconcile the observed performance decrease with how many developers, including myself, have now been leveraging AI to get tasks done in a fraction of the time, tasks that would have taken them hours or days previously. I believe that the <a href="https://en.wikipedia.org/wiki/Pareto_principle?ref=blog.stdlib.io">Pareto Principle</a> is a helpful yardstick. Named after Italian economist Vilfredo Pareto, it is commonly referred to as the 80/20 rule and posits that roughly 80% of effects come from 20% of the causes. Coding agents can now generate working code that mostly works but that might fall short if the goal is 100%.</p><p>In many instances, coding agents can easily accomplish the first 80% of a programming task, generating boilerplate, scaffolding logic, implementing core functionality, and writing a test suite. However, the final 20% of the task, from handling tricky edge cases, adhering to unwritten architectural conventions, ensuring optimal performance, and avoiding code duplication by reusing existing utilities is where the complexity lies. This last mile still requires the developer&apos;s deep, stateful mental model of the project. The rub here is that, by using the AI agent, one may bypass all the little steps which are necessary in the process of building that mental model.</p><p>But does it matter? When working on a crucial piece of a larger, complex system, it definitely does, and I would be hesitant with generative AI. But when working on a well-defined, isolated piece of code with expected behavior for inputs and outputs, why bother? The marginal cost of writing code (long recognized as only a small part of software engineering) is going to zero. In the event that there is a problem with the code, it can simply be thrown away and rewritten. The code that AI agents now generate is of decent quality, well-documented, and capable of adhering to one&apos;s coding conventions.</p><p>This brings to mind the following quote by <a href="https://tidyfirst.substack.com/p/90-of-my-skills-are-now-worth-0?ref=blog.stdlib.io">Kent Beck</a>.</p><blockquote>The value of 90% of my skills just dropped to $0. The leverage for the remaining 10% went up 1000x. I need to recalibrate.</blockquote><p>AI as a force multiplier is why I am long on AI, even though the METR study is a good reminder that we all can easily fall prey to cognitive biases.</p><p>In <a href="https://en.wikipedia.org/wiki/Thinking,_Fast_and_Slow?ref=blog.stdlib.io"><em>Thinking, Fast and Slow</em></a>, Daniel Kahneman gives a classic example for biases driven by the <a href="https://en.wikipedia.org/wiki/Availability_heuristic?ref=blog.stdlib.io">availability heuristic</a>: people overestimate plane crash risks due to vivid media coverage, making such events more &quot;available&quot; to memory than statistically riskier, yet routine, car crashes. Our judgment is swayed not by data, but by the ease of recall. In the case of working with AI agents, observing them build fully-functioning tools in seconds is a very memorable and visceral experience. On the other hand, the slow, frustrating &quot;death by a thousand cuts&quot; experience of auditing, debugging, and correcting the AI&apos;s subtle mistakes is the equivalent of the mundane car crash. It&apos;s a distributed cost with no single dramatic moment.</p><p>Nevertheless, I have no reason to believe that this technology will not continue to improve, and I, for one, am excited about the possibilities. For any big and ambitious project, the amount of tickets to be completed, features to be implemented, and bugs to fix vastly outstrips the available amount of time and human bandwidth to work on them.</p><h2 id="what-future-studies-should-tell-us">What Future Studies Should Tell Us</h2><p>It remains to be seen whether the results of the METR study can be replicated. However, the study clearly demonstrated that experts and developers were overly optimistic about the impact of AI on productivity. This is an important insight that should inform future research.</p><p>In some ways, the study raises more new questions than it answers. It looked at a very particular situation: seasoned experts working in the familiar territory of their own large, mature projects. Future studies by METR and others could vary these conditions. What happens when we throw developers into unfamiliar codebases, where, at least per my anecdotal experience, AI agents shine? Or what about junior developers or new contributors to an established open-source codebase? Under what conditions can AI act as a great equalizer, compressing the skill gap and providing a speed boost rather than slowdown?</p><p>Furthermore, the current study centered on completion time, but faster isn&apos;t always better. One possible follow-up would be a blinded study where human experts review pull requests without knowing if AI was involved. We could then measure things like the number of review cycles, the time spent in review, and the long-term maintainability of the code. This might shed light on when and how AI-assisted development may impact trading short-term speed for long-term technical debt.</p><p>Finally, the field of AI is still evolving at a rapid pace. The synchronous workflow that the study&apos;s setup encouraged could be fundamentally suboptimal. Exploring different interaction models, such as the asynchronous delegation workflow that I&apos;ve moved to, could yield very different results.</p><h2 id="how-to-work-with-ai-now">How to Work With AI Now</h2><p>What follows are my current recommendations for using AI in your daily workflow based on my experiences and the METR study.</p><h3 id="adopt-an-asynchronous-workflow">Adopt an Asynchronous Workflow</h3><p>The biggest drain from using AI is the cognitive load of &quot;babysitting&quot; it. Instead of watching the agent work, adopt an asynchronous model:</p><ul><li>Define one or more tasks (e.g., running a set of commands to audit a codebase for lint errors and documentation mistakes) and then let AI agents work on them in the background (e.g., in separate Git worktrees of your repository), and turn your attention elsewhere.</li><li>Review the completed task(s) later. If the output is flawed, it&apos;s often better to discard it and have the model try again with a better prompt rather than engaging in a frustrating back-and-forth.</li></ul><h3 id="know-what-to-delegate">Know What to Delegate</h3><p>AI can now handle the first 80% of many programming tasks, but the final 20% often requires deep context. The key is to choose the right tasks for AI:</p><ul><li><strong>&quot;Vibe Code&quot; and Prototypes:</strong> use AI for mock-ups or small, isolated tools that can be thrown away. This is where the technology&apos;s speed offers a distinct advantage.</li><li><strong>Verifiable Code:</strong> AI is excellent for tasks that can be fully verified against an existing, robust test suite. The tests act as a safety net to catch the subtle mistakes the AI might make.</li><li><strong>Boilerplate Code:</strong> AI can quickly generate boilerplate code, such as REST API endpoints or form validation, and can do so in a way that follows project conventions.</li><li><strong>Learning and Navigation:</strong> use AI to quickly learn your way around a large codebase, document previously undocumented code, or to get help with tools you use infrequently. Asking LLMs questions can be much faster than hunting through documentation, particularly if that documentation is split across multiple resources.</li></ul><h3 id="use-and-customize-claude-code">Use and Customize Claude Code</h3><p>For tools such as Claude Code, customization is a helpful means of writing down any implicit knowledge about the project that is not readily accessible from the code alone.</p><ul><li><strong>Provide Proper Context:</strong> drag and drop relevant files (this can include images!) into the Claude Code window for the model to use as context for the task at hand. One approach I have found useful is to add TODO comments in the codebase with the required changes, and then have Claude Code work on them. Use the planning mode to have the model think through the task and generate a plan that can be approved before immediately jumping into implementation.</li><li><strong>Use Project Memory:</strong> use <code>CLAUDE.md</code> files to give the model project-specific <a href="https://docs.anthropic.com/en/docs/claude-code/memory?ref=blog.stdlib.io#how-claude-looks-up-memories">memory</a>, specifically on its architecture and unwritten knowledge. You can have multiple <code>CLAUDE.md</code> files in different project sub-directories, and the model will intelligently pick up the most relevant one based on your current context.</li><li><strong>Build Custom Tooling:</strong> use the Claude CLI to build small, automated tools, such as a review bot that flags typos as a daily CRON job. For fuzzy tasks such as pointing out typos or inconsistencies in a PR, it&apos;s best to let Claude generate output that can be verified by a human. For well-defined tasks that can be fully automated, it is better to have Claude produce code that deterministically runs and can be verified.</li><li><strong>Set up Hooks to Automate Actions:</strong> <a href="https://docs.anthropic.com/en/docs/claude-code/hooks?ref=blog.stdlib.io">hooks</a> are a powerful new feature of Claude Code that allows you to run scripts and commands at different points in Claude&apos;s agentic lifecycle.</li><li><strong>Automate Repetitive Actions:</strong> create <a href="https://docs.anthropic.com/en/docs/claude-code/slash-commands?ref=blog.stdlib.io#custom-slash-commands">custom slash commands</a> for frequent tasks performing routine work. Below is an example <code>stdlib:review-changed-packages</code> command that I run to flag any possible errors in PRs that were recently merged to our development branch:</li></ul><pre><code class="language-md">- Pull down the latest changes from the develop branch of the stdlib repository.
- Get all commits from the past $ARGUMENTS day(s) that were merged to the develop branch
- Extract a list of @stdlib packages touched by those commits
- Review the packages for any typos, bugs, violations of the stdlib style guidelines, or inconsistencies introduced by the changes.
- Fix any issues found during the review.
</code></pre><ul><li><strong>Build Custom Tooling:</strong> use the Claude CLI to build small, automated tools, such as a review bot that flags typos as a daily CRON job. For fuzzy tasks such as pointing out typos or inconsistencies in a PR, it&apos;s best to let Claude generate output that can be verified by a human. For well-defined tasks that can be fully automated, it is better to have Claude produce code that deterministically runs and can be verified.</li><li><strong>Set up Hooks to Automate Actions:</strong> <a href="https://docs.anthropic.com/en/docs/claude-code/hooks?ref=blog.stdlib.io">hooks</a> are a powerful new feature of Claude Code that allows you to run scripts and commands at different points in Claude&apos;s agentic lifecycle.</li></ul><h2 id="final-thoughts">Final Thoughts</h2><p>It&apos;s natural to attack a study whose results you don&apos;t like. A better response is to ask what they might be telling you. For me, it tells me there is still a lot to learn about how to use this new, powerful, but often deeply weird and unpredictable technology. One mistake is treating it as the driver in a pair programming session that requires your constant attention. Instead, treat it like a batch process for grunt work, freeing you to focus on the problems that actually require a human brain.</p><hr><p><em>Philipp Burckhardt is a data scientist and software engineer securing software supply chains at </em><a href="https://socket.dev/?ref=blog.stdlib.io"><em>Socket</em></a><em> and a core contributor of </em><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io"><em>stdlib</em></a><em>.</em></p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">financially supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item><item><title><![CDATA[GSoC 2025 Projects Announced]]></title><description><![CDATA[We're thrilled to share that stdlib was awarded five slots for Google Summer of Code 2025.]]></description><link>https://blog.stdlib.io/stdlib-gsoc-2025-projects-announced/</link><guid isPermaLink="false">681d399bed2315029621f0a8</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[Philipp Burckhardt]]></dc:creator><pubDate>Fri, 09 May 2025 02:24:05 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1589652717521-10c0d092dea9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI3fHxsYXB0b3B8ZW58MHx8fHwxNzQ2NzU3MDg0fDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1589652717521-10c0d092dea9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI3fHxsYXB0b3B8ZW58MHx8fHwxNzQ2NzU3MDg0fDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="GSoC 2025 Projects Announced"><p>Today, we are grateful to announce that stdlib, the fundamental numerical library for JavaScript, was awarded five slots in this year&apos;s Google&apos;s Summer of Code (GSoC). We participated in the program last year for the first time, and had four talented students working on a variety of projects. It was a resounding success, which we hope to surpass this year given all <a href="https://blog.stdlib.io/reflecting-on-gsoc-2024/">that we have learned</a> over the past year and a half.</p><p>This achievement comes after a tremendously productive start to 2025. Since January 1st of this year, the stdlib community has:</p><ul><li>Opened two thousand PRs with 1,377 successfully merged.</li><li>Welcomed contributions from 88 different contributors.</li><li>Added 3,452 commits to the repository.</li></ul><p>For GSoC, we received 99 excellent applications from enthusiastic students. Ranking proposals was a tough decision, and we would have loved for a few more projects to be accepted. We are grateful to everyone who applied and encourage those not selected this year to stay connected, continue to contribute to the project, and to apply again next year! In fact, one of this year&apos;s accepted contributors was a repeat applicant, demonstrating how persistence and continued engagement can pay off.</p><p>The accepted projects are listed below. Each project addresses key areas that will expand JavaScript&apos;s potential for technical and scientific applications.</p><p><a href="https://summerofcode.withgoogle.com/programs/2025/projects/opJzlQTz?ref=blog.stdlib.io"><strong>Add LAPACK bindings and implementations for linear algebra</strong></a><br><strong>Contributor:</strong> <a href="https://github.com/aayush0325?ref=blog.stdlib.io">Aayush Khanna</a></p><p>The goal of Aayush&apos;s project is to develop JavaScript and C implementations of LAPACK (<strong>L</strong>inear <strong>A</strong>lgebra <strong>Pack</strong>age) routines. This project aims to extend conventional LAPACK APIs by borrowing ideas from BLIS, thus ensuring easy compatibility with stdlib ndarrays and adding support for both row-major (C-style) and column-major (Fortran-style) storage layouts. This work will help overcome the LAPACK&apos;s column-major limitation and thus make advanced linear algebra operations more accessible and efficient in JavaScript environments.</p><p><a href="https://summerofcode.withgoogle.com/programs/2025/projects/JYSuqCBs?ref=blog.stdlib.io"><strong>Expanding array-based statistical computation in stdlib</strong></a><br><strong>Contributor:</strong> <a href="https://github.com/gururaj1512?ref=blog.stdlib.io">Gururaj Gurram</a></p><p>Gururaj will advance statistical operations in stdlib by introducing convenience array wrappers for all existing strided APIs, thus improving developer ergonomics for common use cases. Additionally, he will develop specialized ndarray statistical kernels with the aim of facilitating efficient statistical reductions across multi-dimensional data.</p><p><a href="https://summerofcode.withgoogle.com/programs/2025/projects/Td3c9qv2?ref=blog.stdlib.io"><strong>Implement base special mathematical functions in JavaScript and C</strong></a><br><strong>Contributor:</strong> <a href="https://github.com/anandkaranubc?ref=blog.stdlib.io">Karan Anand</a></p><p>Karan will implement and enhance lower-level scalar kernels for special mathematical functions in stdlib. The goal is to complete missing C implementations for existing double-precision packages, develop new single-precision versions, and ensure consistency, accuracy, and IEEE 754 compliance. These enhancements will provide developers with the most comprehensive set of high-precision mathematical tools for scientific computing in JavaScript.</p><p><a href="https://summerofcode.withgoogle.com/programs/2025/projects/lKDCoGBz?ref=blog.stdlib.io"><strong>Achieve ndarray API parity with built-in JavaScript arrays</strong></a><br><strong>Contributor:</strong> <a href="https://github.com/headlessNode?ref=blog.stdlib.io">Muhammad Haris</a></p><p>Haris will extend stdlib&apos;s ndarray capabilities by implementing familiar JavaScript array methods like <code>concat</code>, <code>find</code>, <code>flat</code>, <code>includes</code>, <code>indexOf</code>, <code>reduce</code>, and <code>sort</code> for multi-dimensional arrays. The project will develop high-performance C implementations with Node.js native add-ons for compute-intensive operations. These enhancements will allow JavaScript developers to work with multi-dimensional arrays as easily as built-in arrays, significantly expanding JavaScript&apos;s capabilities for scientific and numerical computing.</p><p><a href="https://summerofcode.withgoogle.com/programs/2025/projects/NJC5LuLO?ref=blog.stdlib.io"><strong>Add BLAS bindings and implementations for linear algebra</strong></a><br><strong>Contributor:</strong> <a href="https://github.com/ShabiShett07?ref=blog.stdlib.io">Shabareesh Shetty</a></p><p>Shabareesh will expand stdlib&apos;s BLAS (<strong>B</strong>asic <strong>L</strong>inear <strong>A</strong>lgebra <strong>S</strong>ubprograms) support by implementing missing Level 2 (vector-matrix) and Level 3 (matrix-matrix) operations in JavaScript, C, Fortran, and WebAssembly. The project will focus on key dependencies for LAPACK routines and create performance-optimized APIs that work in both browser and server environments. These enhancements will provide essential building blocks for developing high-performance machine learning and statistical analysis applications on the web.</p><p>We&apos;re excited to see these projects develop over the coming months. Each contribution will significantly enhance stdlib&apos;s capabilities and make advanced mathematical and statistical operations more accessible to the JavaScript community. The work done by these talented contributors will help bridge the gap between traditional scientific computing environments and JavaScript, furthering our mission to create a comprehensive, high-performance standard library for JavaScript.</p><p>We&apos;d like to extend thanks to Google for their continued support of open-source development through the Summer of Code program, and we look forward to sharing updates as the above projects progress over the course of this summer. In addition to watching for more posts on this blog, you can follow development by joining our <a href="https://app.gitter.im/?ref=blog.stdlib.io#/room/#stdlib-js_stdlib:gitter.im">community chat</a>. We also hold regular&#xA0;<a href="https://github.com/stdlib-js/meetings/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3A%22Office+Hours%22&amp;ref=blog.stdlib.io">office hours</a>&#xA0;over video conferencing, which is a great opportunity to ask questions, share ideas, and engage directly with the stdlib team.</p><p>We hope that you&apos;ll join us in our mission to advance cutting-edge scientific computation in JavaScript. Start by showing your support and starring the project on GitHub today: <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">https://github.com/stdlib-js/stdlib</a>.</p><hr><p><a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">stdlib</a> is an open source software project dedicated to providing a comprehensive suite of robust, high-performance libraries to accelerate your project&apos;s development and give you peace of mind knowing that you&apos;re depending on expertly crafted, high-quality software.</p><p>If you&apos;ve enjoyed this post, give us a star &#x1F31F; on <a href="https://github.com/stdlib-js/stdlib?ref=blog.stdlib.io">GitHub</a> and consider <a href="https://opencollective.com/stdlib?ref=blog.stdlib.io">financially supporting</a> the project. Your contributions and continued support help ensure the project&apos;s long-term success and are greatly appreciated!</p>]]></content:encoded></item></channel></rss>