13 Oct 2026
Planet Python
PyCoder’s Weekly: Issue #756: 3.15 Released For Real This Time, Muse, and More (2026-10-13)
#756 - OCTOBER 13, 2026
View in Browser »
The 5 Most Exciting New Features of Python 3.15
This article explains the 5 best new features of Python 3.15 with clear examples and explanations.
RODRIGO GIRÃO SERRÃO
How Fast Is Python 3.15?
Miguel benchmarks Python 3.15 RC3 and compares it to the performance of past releases as well as PyPy and even other languages.
MIGUEL GRINBERG
CodeAF: 2x OpenCode's and 4x Claude Code's solves, same model
On DeepSWE, CodeAF solved 2× as many real GitHub issues as OpenCode and nearly 4× as many as Claude Code on the same open model, at up to 4.8× less per solved issue. A new open-source coding harness built for open models like DeepSeek, Qwen, GLM and Kimi, and it works with closed models too. Try CodeAF on GitHub
AGENTFIELD sponsor
What Is Meta Muse? A Plain-English Guide to Meta's New AI
What is Meta Muse? Learn what Meta's AI agent can do, what it costs, how it handles your data, and where Python fits in. No coding required.
REAL PYTHON
Codex for Python Developers: Hands-On Agentic Coding Course
In this 2-day live course, you'll build a complete Python CLI app from an empty directory with Codex CLI, an AI agent that reads your files, runs your tests, and fixes errors in your terminal. Sessions run November 7-8 on Zoom.
REAL PYTHON
Articles & Tutorials
P Is for Python Enhancement Proposal (PEP)
PEPs are proposals for how Python the programming language is changed. Even if you'll never interact with them, reading them and the discussion around them will make you a better communicator.
JUHA-MATTI SANTALA
Codemoo: Demonstrating How Coding Agents Work
How do you assemble the core pieces of a coding agent? How are developers defining projects through conversation and introspection? This week on the show, Geir Arne Hjelle returns to talk about his recent project to demonstrate how coding agents work under the hood.
REAL PYTHON podcast
The Things You Own End Up Owning You
A recap of Pratham's Quansight internship porting NumPy extension modules to the Limited API: heap types, swapping macros for function calls, and the side quest it started, getting NumPy ready for subinterpreters.
PRATHAM HOLE
Why Most Data Science Notebooks Die After Day One
Six habits that keep a notebook runnable after you close your laptop, including establishing imports and setup in your first cell, keeping to one function per cell, and more.
NATE ROSIDI
Generate Images in Python With OpenAI's GPT Image API
Learn how to generate images from text prompts with OpenAI's GPT Image API in Python, tune their size and quality, and edit them with a follow-up prompt.
REAL PYTHON
Hugging Face Transformers: Leverage Open-Source AI in Python
Get hands-on with Hugging Face Transformers in Python. Download, run, and inspect pretrained open-source AI models, and speed up inference on GPUs.
REAL PYTHON
Saving Jet Fuel
This article shows you how to use the scikit-decide library to determine an optimal flight path to save jet fuel for a Boeing 787-9 Dreamliner.
MARK LITWINTSCHIK
Towards Async Transactions in Django
async with transaction.atomic() is coming to Django, hopefully for 6.2. This post talks about how we got there at Django on the Med, and what the rules will be.
CARLTON GIBSON
How We Built an Async-Aware Python Profiler
Learn how Datadog made Python profiling async-aware while reducing profiler overhead and preserving context across asyncio tasks.
KOWALSKI & GERRING
First Steps Into Memory Management in Python
A quick introduction to how Python manages memory under the hood and how that might effect your code.
DANIELL BASTOS
Show and Hide Wagtail Admin Fields Without JavaScript
Learn how to show and hide Wagtail admin fields easily without writing any JavaScript.
TIM KAMANIN
Projects & Code
polynx: pandas-Style Query/Eval Strings for Polars
GITHUB.COM/LOWELLWINSTON • Shared by Lowell Winston
nvmon: A Fancy NVIDIA GPU Monitor for the Terminal
GITHUB.COM/HAN-DONGHEUN • Shared by Han DongHeun
pyEQL: An Interface for Water Chemistry
GITHUB.COM/KINGSBURYLAB • Shared by Michael Mulqueen
Events
Weekly Real Python Office Hours Q&A (Virtual)
October 14, 2026
REALPYTHON.COM
PyCon NL 2026
October 15 to October 16, 2026
PYCON-NL.ORG
PyData Bristol Meetup
October 15, 2026
MEETUP.COM
PyLadies Dublin
October 15, 2026
PYLADIES.COM
Chattanooga Python User Group
October 16 to October 17, 2026
MEETUP.COM
PyCon Taiwan
October 17 to October 19, 2026
PYCON.ORG
PyCon Panamá 2026
October 22 to October 24, 2026
PYCON.PA
PyHo 2026
October 23 to October 25, 2026
PYTHONHO.COM
PyBeach 2026
October 24 to October 25, 2026
PYBEACH.ORG
Happy Pythoning!
This was PyCoder's Weekly Issue #756.
View in Browser »
[ Subscribe to 🐍 PyCoder's Weekly 💌 - Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
13 Oct 2026 7:30pm GMT
PyCharm
Two things are true about Python: It's the most popular programming language in the world, and it's the most common companion language for Go developers. How do we know that? From the Developer Ecosystem 2026 survey by JetBrains.
But we also know a lot more about the developers who use these two languages - both from quantitative data from different surveys, as well as qualitative data from our interviews with professionals who switched from Python to Go.
In this article, we share findings from these sources, going well beyond the simple syntax comparisons you will usually find. We will look at how the two languages differ, what the surveys tell us about the people who use them, and what our interviews say about the trade-offs between Python and Go, so that if you're considering making the leap, you don't have to dive in blind.
TL;DR
- The article compares Python and Go across language design, performance, tooling, developer profiles, and migration experiences.
- Python favors expressive code and rapid iteration; Go favors explicit, standardized code that is easy to maintain across teams.
- Go excels in raw performance and concurrency, and is widely used in cloud infrastructure. Python remains stronger for machine learning, data science, and scientific computing.
- Go developers are typically more infrastructure-focused and more senior. Go is rarely someone's first language, whereas Python is very beginner-friendly.
- Python leads in building AI models, yet Go developers create AI integrations at nearly the same rate: 46% vs 44%.
- Moving to Go rarely means abandoning Python. Most teams use both, with Go for services and infrastructure and Python for AI and data workloads.
A note about the data
Unless stated otherwise, all survey figures come from the JetBrains Developer Ecosystem Survey 2026 (28,945 responses, fielded May-July 2026). We compare two groups: developers who selected Go among their primary languages (1,836) and developers who selected Python (11,298). The groups overlap, with 619 respondents selecting both languages. Therefore, every gap below is a conservative estimate of the real difference. Some questions were shown to only a part of each group, so bases are provided for reference. The qualitative material comes from interviews with developers who moved production workloads from Python to Go. We conducted the interviews between April and May 2026 and included seven participants who began using Go within the past year.
Python vs Go - languages compared
Core philosophy
On paper, Python and Go sound like they'd get along. Python lays out the core principles in the Zen of Python: Simple is better than complex, readability counts, there should be one obvious way to do it, etc. Go, as per Effective Go, "focuses on simplicity, reliability, and efficiency", and is "specifically designed to make it easy to build software at scale".
In practice, Python often optimizes for the person writing the code, offering multiple ways to say the same thing. Go optimizes for the person (or, nowadays, possibly the agent) reading someone else's code two years later, so it picks one way to say most things and makes you spell it out. The goal is for all Go code to look like other Go code.
We point this out right at the beginning, because however similar these two philosophies look, this difference in approach underlies almost all the other language design differences that follow.
Ease of use and learning curve
Python is arguably one of the easiest programming languages to learn among those widely used in production. The syntax resembles natural language, the core set of constructs is small, and beginners can focus on programming ideas instead of language mechanics, leading to less frustration and faster results. Surveys consistently show Python to be one of the most popular programming languages (if not the most popular). In 2026, 10% of Python developers have been coding for less than a year, 23% are students or working students, and 19% hold junior positions, showing the language has a strong early-stage user base.
Python's popularity among early learners is almost self-perpetuating. Initially, the language was well-suited to introductory courses and learning materials largely because it lets beginners print "Hello, world" with little ceremony, bypassing much boring theory in favor of real outputs. It also has the added benefit of being a generalist language that can handle a variety of use cases. Later, the sheer number of introductory courses and learning materials made it a natural choice for anyone who wanted to pick up programming but didn't know where to start.
It's not the same case with Go. In fact, you would be hard-pressed to find courses that teach you programming through Go. There are two reasons for that. First, Go 1.0 was released in 2012, long after Python had already become firmly embedded in CS curricula. The other is that Go solves problems that beginners don't have. Explicit error handling, static types, and interfaces, which we'll discuss later, all pay off across a large codebase maintained by a team over years. Go also has a much narrower set of implementations than Python, which makes it even less appealing for beginners.
That said, Go was also designed to be easy to learn, but for a different reason: Any large team should be able to onboard a new engineer quickly. Many Go developers will say that if you already know general programming concepts, you can become productive in Go in a matter of days or weeks. Developers we talked to said that Go "feels as easy to write as Python" and that it "strikes a good balance between Python's simplicity and Java's explicit nature".
Syntax and readability
When you read Python, you can often follow it even without programming experience, because it reads relatively close to English. Python is dynamically typed, so type declarations are optional, though in practice, many companies and large codebases now write Python with type hints throughout, checked by tools like mypy or Pyright. Most of the ecosystem follows the formatting conventions set out in PEP 8, but they are still optional, and so some teams diverge from them.
Go, by contrast, is explicit and deliberately limited, which contributes to the cross-team readability we mentioned. It is statically typed, which makes it noticeably more verbose than Python. That was the main syntactic complaint raised by the developers we interviewed. Formatting in Go is not a matter of preference: gofmt will shape your code into the canonical form, whether you like the conventions or not.
One syntactic difference that developers consistently pointed out as a big adjustment when moving from Python to Go was error handling. Python lets you push failure handling to the edges of a function with try / except. Experienced Go developers clutch their pearls at the sight of that.
# Python: handle failure where it is convenient
try:
profile = get_user(user_id)
except UserNotFound:
return render_404()
// Go: handle failure where it happens
profile, err := getUser(userID)
if err != nil {
if errors.Is(err, ErrUserNotFound) {
return render404(w)
}
return fmt.Errorf("get user %s: %w", userID, err)
}
The Go version is longer, and in a large handler, developers will find themselves writing the if err != nil boilerplate ad nauseam. In return, they get control flow with no invisible jumps: Every path a value can take is explicit. Both approaches come with trade-offs.
Type system
Python's dynamic typing checks types at runtime. This gives developers flexibility in writing and can speed up iteration, but it also means some type errors only show up when the code runs. The flexibility extends to the object model, which relies on duck typing: The code cares less about what an object is than what it can do. The developers we interviewed said they sorely missed duck typing, as it makes testing and mocking more difficult in Go.
Go checks types before the program runs. This results in fewer type-related failures reaching production and makes refactoring safer, but also causes code verbosity, as we touched on earlier.
Object model and polymorphism
Python is object-oriented in the way that most developers first learn the term. Everything is an object, and classes inherit from other classes (several at once, if you insist). Polymorphism works in two ways: down the class hierarchy when a subclass overrides its parent's method, and sideways through duck typing, where anything with a read() method can be handed to code that expects a file.
Go has none of that hierarchy. There are no classes, no inheritance, and no way to declare that one type is a subtype of another. Instead, structs have methods attached to them, as well as interfaces that types satisfy implicitly without ever naming them.
# Python: the implementation announces its role
class Store(ABC):
@abstractmethod
def get(self, key: str) -> bytes: ...
class RedisStore(Store):
def get(self, key: str) -> bytes:
...
// Go: the consumer declares what it needs; RedisStore never mentions Getter
type Getter interface {
Get(key string) ([]byte, error)
}
func handleRead(g Getter, key string) ([]byte, error) {
return g.Get(key)
}
Notice how the dependency runs. In Python, RedisStore inherits from Store, so the abstraction sits with the implementation. In Go, handleRead declares the one method it actually calls, and RedisStore never learns that Getter exists. That's why Go developers say to "accept interfaces, return structs", and that's why interfaces stay small - io.Reader and io.Writer have a single method each.
Performance and speed
Go follows a traditional compilation model, producing a native binary. Python, on the other hand, takes a hybrid approach: Source code is compiled to bytecode, which the interpreter then executes.
As most compiled languages do, Go wins in terms of raw speed. You can compare the patterns across latency, throughput, and startup time on The Computer Language Benchmarks Game. Microbenchmarks like these don't really translate directly to real workloads, and we wouldn't be surprised if you made nothing of them. Our interviewees told us what the difference meant in production for them: One team migrated to Go after cold starts on AWS Lambda in Python exceeded 10 seconds; another measured a tenfold improvement in request times after rewriting their Python service in Go.
But raw language speed matters only when your service is actually compute-bound or latency-sensitive, and plenty of services are neither. Equally importantly, the Python interpreter is not slow where it counts most for one of its largest user bases. In machine learning, data work, and numerical computing, libraries like NumPy and PyTorch offload expensive operations to optimized native code, making interpreter overhead much less relevant. When we asked migrating developers where they decided to keep Python code, they confidently listed all AI and ML workflows - LLMs, chatbots, RAGs, and model training.
Memory management
Memory management is another important part of the performance discussion. Both languages manage memory for you, but differently: Go uses a tracing garbage collector, while CPython uses reference counting alongside a cyclic garbage collector. This affects what developers can fine-tune and what they need to design around.
Go's GC runs concurrently with the program and is designed to minimize stop-the-world pauses. Developers can tune this behavior: GOGC and GOMEMLIMIT set the pacing, and the memory profile (heap and allocs) tells you when a service allocates too hard.
In CPython, an object is typically freed the moment its last reference disappears. Memory use is predictable, and pauses are rarely worth measuring, but the cost is spread across every operation, and there's little to room tune it.
Concurrency and parallelism
Even though both languages support concurrency, developers we talked to cited better concurrency as the reason why they switched from Python to Go.
Goroutines are central to Go's design. They are lightweight threads managed by the runtime. They are cheap to create, carry little overhead, and scale to thousands of concurrent operations. The runtime handles the scheduling, which makes the model simpler than in Python - there is no separate async/await syntax, so a function is just a function. However, if you start to spawn goroutines without controlling their lifecycle, you'd better be ready to deal with race conditions, leaks, and deadlocks before long.
The other half of the concurrency model in Go are channels - typed conduits that pass values between goroutines and synchronize them. Instead of guarding shared state with a lock, Go can pass the value to whichever needs it next. A select statement waits on several channels at once, which is how Go expresses timeouts, cancellation, and fan-in using built-in language constructs. These very same primitives also produce common Go bugs: goroutine leaks and more deadlocks.
Meanwhile, Python relies on standard libraries, single-threaded event loops, and sub-processes to work around interpreter constraints. It offers threading, but in CPython, the global interpreter lock (GIL) has historically prevented threads from running Python bytecode simultaneously, making it ineffective for CPU-bound parallelism. For I/O-bound concurrency, there is asyncio, and for real parallelism there is multiprocessing, but that adds memory overhead and requires inter-process communication.
It's worth noting that the GIL itself is no longer a necessity - starting with Python 3.13, PEP 703 introduced an officially supported free-threaded build, and 3.14 continues that work. Most production code still runs with the GIL in place, but with each new release, the claim that "Python can't do real threading" is becoming less true.
# Python: async/await, and the coloring that comes with it
async def fetch_all(urls):
return await asyncio.gather(*(fetch(u) for u in urls))
// Go: ordinary functions run concurrently
var wg sync.WaitGroup
for _, u := range urls {
wg.Add(1)
go func() {
defer wg.Done()
fetch(u)
}()
}
wg.Wait()
The approach to concurrency gives Go much of its practical advantage in high-throughput services, and having experienced both, our interviewees praised Go for being "async by default" and better suited for high-concurrency components, and they described it as having a superior concurrency model that's highly performant and appealing for real-world use cases.
Libraries, frameworks, and IDEs
Go's self-contained ecosystem
Go was never built as just a programming language, but as an ecosystem. As the Go team puts it, the goal was "an end-to-end platform with tooling all around the software development lifecycle" (Google for Developers), with formatters, test frameworks, dependency management, and security tools included in the toolchain, alongside a standard library that's comprehensive enough to make external frameworks optional, if not irrelevant.
The Developer Ecosystem 2026 survey shows how successful the Go team has been in achieving that goal. For example, among Gophers, the standard html/template and text/template library packages are used by 31% and 22% of developers respectively, whereas the only other significant alternative - templ - is used by 11%.
Almost half of Gophers either don't write unit tests or don't use testing frameworks: 14% don't write unit tests at all, and 35% don't use frameworks for testing - the testing package provides everything they need in that regard. Others may also reach for tools such as Testify (31%) or GoMock (25%). The remaining libraries are far less popular.
For web development, 46% of developers use the standard net/http library, compared to 48% who use Gin. This proves that where a third-party framework exists, it doesn't compete with the many other frameworks, but only with the standard library. Oftentimes, it loses.
Go developers
Libraries and frameworks Go developers use
Template engines used for Go development
Which template engines do you use for Go development, if any?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Go section (n = 1,529). Multiple answers allowed.
Testing frameworks and mock libraries in Go
Which testing frameworks or mock libraries do you regularly use, if any?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Go section (n = 1,518). Multiple answers allowed.
Go web frameworks in regular use
Which Go web frameworks do you regularly use, if any?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Go section (n = 1,519). Multiple answers allowed.
Python's broad ecosystem
Python's ecosystem works the other way around. The Python Package Index (PyPI) is vast and mature, and where the standard library stops, several strong alternatives tend to compete.
Take web frameworks, for example. Half of Python developers use FastAPI, and Django (31%) competes closely with Flask (30%). The data science landscape is more fragmented, and developers use those libraries simultaneously: 69% use NumPy, 68% use pandas, 50% use PyTorch, 49% use Matplotlib, etc. With Python, there's often no clear leader, and choosing the right framework or library is part of the job.
Python developers
Frameworks and packages Python developers use
Web frameworks used with Python
What web frameworks / libraries do you use in addition to Python?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Python section (n = 4,276). Multiple answers allowed.
Data science packages used with Python
What data science packages do you use in Python?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Python section (n = 4,277). Multiple answers allowed.
IDEs & editors
When it comes to editors, we see a similar pattern unfold. Go has an excellent language server, which makes general-purpose editors a viable alternative to a Go-specific IDE. When asked which IDEs or editors they use for Go development, 49% reported using GoLand, while 48% reported using VS Code.
Go developers
IDEs and editors used for Go development
Which IDEs or editors do you use for Go development?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Go section (n = 1,529). Multiple answers allowed.
One reason is how much of Go's surrounding ecosystem developers can access without having to assemble it themselves. GoLand installs with a test runner, debugger, coverage, and profilers wired into the toolchain. The analysis runs across the whole project, rather than only the open file. Interprocedural nil checks and unhandled-error inspections can catch the mistakes a Python developer might otherwise only see at runtime. Suffice it to say, Alan Donovan of the Go team has also described traditional IDEs like ours as setting "the gold standard" for refactoring because of their tight integration between the analysis logic and the user interface.
Python developers
Main IDE or editor for Python development
Which IDE or editor do you use the most for Python development?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who answered the Python section (n = 4,276). One answer per respondent.
The Python side is more fragmented and has more Python-specific options, such as Jupyter Notebook and, of course, PyCharm. The latter is used by 30% of Python developers (PyCharm - 22%, PyCharm Pro - 8%), with VS Code at 41%. Notebooks explain much of the fragmentation, since data and service work don't necessarily require the same toolset. Whatever you build in Python, PyCharm has first-class support for your stack, your frameworks, and your workflow - for web, data, and ML workflows - with notebooks running alongside a debugger and type checker. It parses your code and resolves usages, types, and dependencies throughout your entire project. So you always know exactly what your code does and what will break if it changes, for you and your agents alike.
If you use both Go and Python - as a quarter of Gophers do - it's worth noting that both GoLand and PyCharm are built on the same platform, so keymaps, shortcuts, and settings sync between them. GoLand also supports Python functionalities through the Python Community Edition plugin.
Python vs Go - broader landscapes
The language itself is one thing, but many other factors go into deciding which language you choose to work with. Developers consider what the languages are used for, who uses them, and how they're maintained. In this section, we'll provide insights on the factors that shape the broader landscapes of Python and Go.
Go developers are more senior
Across all questions about age, experience, and seniority in the Developer Ecosystem 2026 survey, Gophers tend to be further along in their career than Python developers.
On overall professional coding experience (not just experience in their main programming language), 20% of Go devs report 16 years or more, compared to 12% among Python developers. At the other end, 9% of Gophers have 1-2 years of experience, compared to 20% of Python developers.
Most Go professionals have senior roles, at 60%, with only 2% being trainees and 10% juniors. Meanwhile, 42% of Python professionals are seniors; trainees (6%) and juniors (19%) make up a quarter of the cohort.
72% of Go developers are employed full-time, compared to 51% of Python developers. Students and working students make up 8% of Gophers, compared to 23% of the Python population.
Finally, by age, the largest group of Go developers is aged 30-34 (23%), compared to Python's largest group, aged 21-24 (22%).
These differences align with the point we made earlier: Python is a very popular first language for learners, while Go is almost never chosen as a first language and instead is picked up by more experienced developers later in their careers.
It's important to keep this in mind as you read the following sections on developer demographics, because a lot of these numbers may look like differences between two languages, where in reality, they're just differences between a senior population vs a general one that you would see regardless of what ecosystems you compare.
Go vs Python developers
Experience and seniority
Professional coding experience
How many years of professional coding experience do you have?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
Position level
What is the level of your current position?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,531, Python n = 6,891. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
Employment status
Which of the following best describes your employment and involvement in software development?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
Age
What is your age range?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
Salary follows seniority
Salary bands clearly show how experience affects other demographic data. Go developers are better represented in the top bracket: 9% report earning more than $180,000 a year, compared to 6% of Python programmers. Meanwhile, Python users cluster more in the lowest brackets.
Go vs Python developers
Annual salary, USD
Salary bands in USD, converted from local currencies.
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,115, Python n = 5,004. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
However, if we look only at full-time developers, the differences are no longer statistically significant. The premium is attached to the seniority and employment status, not the primary language. In other words, learning Go itself will not guarantee you a higher salary, but the roles that require Go generally pay better.
What they build
The Developer Ecosystem survey also asks people what functionality their code implements.
Go developers more frequently reported:
- 69% - providing APIs and services (Python - 41%)
- 63% - integrating with APIs and services (Python - 47%)
- 51% - application logic and workflows (Python - 37%)
- 47% - user interface (Python - 41%)
- 35% - libraries and frameworks (Python - 26%)
Meanwhile, Python developers reported higher rates for:
- 38% - data processing and analytics (Go - 30%)
- 36% - artificial intelligence and machine learning (Go - 20%)
- 32% - data science and data analytics (Go - 15%)
The question of where their code is executed adds more context: A vast majority of Go developers target server, infrastructure, or cloud environments (74% compared to 57% of Python developers. On the other hand, 66% of Python developers target the desktop (Go - 47%).
Python is clearly a general-purpose language with a stronghold in AI, ML, and data work that favors local execution, while Go is heavily oriented towards networked services and infrastructure.
There is, however, a particularly interesting line item in the set: integration with AI. While AI development per se is a Python domain, integrations are not. 46% of Go developers report implementing AI integrations, against Python's 44%, almost equal numbers. Asked about the types of development they do at work, 51% of Python developers reported working with AI and AI tools, compared to Go's 48%. Go engineers may not train the models, but they are building AI-powered products at roughly the same rate as Python developers.
Go vs Python developers
What Go and Python developers build
What their code implements
Which specific functionality does your code implement?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
Where their code runs
On which platforms is your code executed?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
Types of development at work
Which types of development are you involved in at work?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,595, Python n = 7,427. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
DevOps: Same job, different toolbox
One other point of convergence between Python and Go developers that deserves its own section is DevOps. Both groups are involved in that area, though Python developers (31%) somewhat less than Gophers (45%). The two groups also tend to use different tools.
- For orchestration, Go developers are more likely to use tooling overall, and especially Kubernetes. Only 8% of Go developers don't use container orchestration tools (compared to 17% for Python); 58% use Kubernetes (compared to 39%). The engineers we talked to cited Go's deep integration with Kubernetes as one of the reasons they migrate entire services from Python to Go.
- For configuration management, Terraform leads both groups. However, Python developers lean more toward cloud-native IaC tools (29% for Python, 23% for Go) or use nothing (21% for Python, 15% for Go), while Go developers choose GitOps more often (27% for Go, 21% for Python).
- When it comes to DevOps practices, Go developers report using them more often overall, with one exception: AI-driven operations (12% of Go developers and 18% of Python developers). Python developers are also more likely to use no DevOps practices at all (6% for Python, 2% for Go).
So even if you move from Python to Go in the same type of role, the toolset change might be as big an adjustment as the language change itself.
Go vs Python developers
DevOps tools and practices
Container orchestration tools
Which container orchestration tools or services do you use?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,435, Python n = 7,242. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
Configuration management and IaC tools
Which configuration management or IaC tools do you use?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 930, Python n = 3,109. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
DevOps practices in use
Which of the following DevOps practices do you or your team currently use?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 930, Python n = 3,110. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
Operating systems
A curious difference surfaced when we asked developers about the operating system they use for their development environment. Go developers work on macOS (70%) and Linux (57%) significantly more than on Windows (44%). Meanwhile, Python developers use Windows first (66%), then split almost evenly between macOS (54%) and Linux (52%).
For developers planning to migrate to Go, sticking with Windows doesn't have to complicate deployment, even when the target is a Linux server. For pure Go, building a Linux binary from any of the three operating systems takes no more than two environment variables, while a Python deployment still has to find a matching interpreter and native packages, wherever it ends up.
Go vs Python developers
Operating systems for development environments
On which operating systems are your development environments?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,298. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
Two different approaches to AI
We've already discussed using Python and Go for AI development, but what about using AI for Go and Python development? Both groups use AI heavily at work, but there's a difference in how and what they use it for.
Go developers report using AI daily for tasks such as editing code across multiple files (60% vs 52%), agentic development of features or programs (51% vs 41%), generating commit messages (51% vs 36%) and tests (47% vs 34%), or performing code reviews (39% vs 34%).
Meanwhile, Python developers lead on one task: learning new things about coding and software development (38% of Python developers vs 31% of Go developers), which is consistent with earlier data showing a larger early-career population among Python developers.
There is, however, a long list of tasks where the two groups are indistinguishable: refactoring, debugging, checking code for potential issues, asking general questions, or generating boilerplate - even though you'd expect Go developers to jump on the last one much more, considering the verbosity of the language.
Go vs Python developers
Tasks they use AI tools for every day
How often do you use AI tools for each of the following tasks at work? Share answering "Every day".
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Respondents who rated these tasks (Go n = 993, Python n = 5,056); bases vary slightly by task. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
So AI-assisted coding is common in both ecosystems. Go developers have simply wired it into the production chores of a maintenance-heavy codebase: commits, tests, reviews, and multi-file edits.
The groups also tend to use different tools. Go developers are more likely to use terminal and agentic tools like Claude Code (45% vs 40%), OpenAI Codex (24% vs 17%), Cursor (17% vs 12%), and OpenCode (12% vs 6%). Python developers, in turn, reach more for general-purpose assistants and Google or Microsoft surfaces like ChatGPT (20% vs 16%), Google Antigravity (9% vs 5%), and Microsoft 365 Copilot (4% vs 1%).
Go vs Python developers
AI tools used for coding at work
Which of these AI tools do you use for your coding and other development-related tasks at work?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,482, Python n = 6,747. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. * Statistically significant difference (p < 0.05, adjusted).
One number that has to change
Software development remains a heavily male-dominated field, and the gap is particularly pronounced in Go, which - as it's typically people's second language - inherits whatever the pipeline hands it and exacerbates it further. In our sample, only 1.8% of Go developers identify as female, compared to 5.8% of Python developers.
Go vs Python developers
Gender
What is your gender?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,833, Python n = 11,284. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. * Statistically significant difference (p < 0.05, adjusted).
Transitioning from Python to Go
One-way path well traveled
You may ask why we're focusing on transitioning from Python to Go, not the other way around. The data leaves little doubt about the path developers are taking. Python is already the most common second language among Go developers - 35% of Gophers declare it as their other primary language. But most Go developers (70%) say they have no intention of adopting another language in the next 12 months, and if they do, they name Rust (16%), rather than Python (2%). On the other hand, 10% of Python developers (a much larger cohort in terms of absolute numbers) plan to pick up Go, roughly 5.5 times the rate at which Go developers plan to pick up Python.
Go vs Python developers
Languages they plan to adopt in the next 12 months
Do you plan to adopt or migrate to other languages in the next 12 months? If so, which ones?
Source: JetBrains Developer Ecosystem Survey 2026, weighted data. Base: Go n = 1,836, Python n = 11,295. Go and Python developers are respondents who selected the language among their primary languages; those who selected both are counted in both groups. Multiple answers allowed. n/a: respondents already use this language as a primary one. * Statistically significant difference (p < 0.05, adjusted).
Why make the switch from Python to Go?
Despite working in different roles and on different products, the developers we interviewed gave consistent reasons for transitioning from Python to Go. These were:
- Better performance and speed, including cold starts, latency, and operating cost.
- Easier and more effective concurrency model.
- Type safety that catches failures that would otherwise reach production at compile time.
- Proximity to the platform, since Kubernetes and much of the cloud-native toolchain are written in Go, so teams working on that infrastructure already interact with Go daily.
What they gained and what they lost
Perceived potential gains are one thing, but did Go actually deliver? According to the developers we interviewed, it did in the areas described above. But they also found benefits they weren't expecting: predictable formatting and linting that contributed to "clean code", out-of-the-box tooling, and simplicity comparable to Python's.
But Go also has flaws that are obvious to developers coming from Python. Just like the reasons for adopting Go were consistent, so were the complaints:
- Explicit error handling that's fundamentally different from Python, less intuitive, and more repetitive.
- Overall verbosity and opinionatedness, with more lines needed to convey the same behavior and fewer ways to express it.
- An object model that makes testing and mocking noticeably more difficult.
- Library gaps, especially for testing.
Did they really leave?
"Migrating", "transitioning", and "switching over" may all sound like final decisions to leave Python behind, but that's not really the case. Not one of the developers we interviewed removed Python from their stack completely. They kept it for artificial intelligence and machine learning, data science, and pipelines on platforms that only support Python, as well as simply because they work on larger teams that already know Python and are productive in it.
The realistic outcome of "moving to Go" is not becoming a monoglot, but having a polyglot codebase where each language is used for what it's best suited for.
Conclusions
So, which language should you choose? Is it worth dropping Python in favor of Go? We hope that by now the answer is clear - it's not a matter of which language is better, but which one is a better fit. Based on our data and developer testimony, here's what we found.
Go may be a better fit if:
- Performance is crucial for your app: Latency, throughput, or cold starts are problems you actually have and can measure.
- The workload is concurrent, especially if it is I/O-heavy.
- The service is long-lived and maintained by a team, not one person.
- The system already depends heavily on Kubernetes and the rest of the cloud-native toolchain.
Python may be a better fit if:
- The work is machine learning, data science, or numerical computing.
- Your platform only accepts Python, as managed ETL and notebook environments frequently do.
- Iteration speed matters more than runtime speed, which is often the case for internal tooling and prototypes.
- The library you depend on has no Go equivalent; for a lot of the scientific stack, there isn't one.
Language features alone rarely determine the best choice. When deciding what to build with, the teams weigh in the toolchain they already run, the languages their colleagues already know or are willing to learn, and how much of the existing system they are willing to change. Those things carry more weight than any benchmark, and they are why developers we talked to ended up using both languages, instead of choosing one.
Frequently asked questions
Can Go replace Python completely?
For a lot of backend work, yes, in principle. In practice, it doesn't. None of the developers we interviewed removed Python from their stack completely. They kept it for machine learning and data science, for pipelines on platforms that only accept Python, and because the teams around them already know it. In the Developer Ecosystem 2026 survey, about a quarter of Go developers report using Python in the same project.
Is Go good for data engineering?
It depends on which end of the pipeline you mean. Go works well for moving data around, including ingestion services, stream processing, API integrations, and CLI tooling, and 30% of Go developers report working on data processing and analytics, compared with Python's 38%. The analytical end is a different story: Only 15% of Gophers do data science and data analytics, against 32% of Python developers, and the library ecosystem reflects that.
How long does it take a Python developer to learn Go?
Days to weeks for the language itself. The syntax is small, gofmt settles the formatting arguments, and developers we talked to said Go "feels as easy to write as Python". What takes longer is everything around it: system concepts such as pointers, interfaces, goroutines, and channels, as well as the habits Go asks you to change, from explicit error handling to designing test seams instead of patching at runtime.
The bigger adjustment may not be the language after all. Go work tends to sit closer to Kubernetes, Terraform, and GitOps, so if you're moving into a Go team from a Python one, budget as much time for learning the toolchain as for the syntax.
Is Go good for machine learning?
For training models, probably not. 20% of Go developers work on artificial intelligence and machine learning, against 36% of Python developers, and the developers we interviewed were blunt about why: Python has the libraries, while Go lacks equivalents.
When it comes to building products around the models, it's a different story. 46% of Go developers implement AI integrations, against Python's 44% - a negligible difference. Gophers generally aren't training the models, but they sure are serving them.
Can Go and Python be used in the same project?
Not only can they be used together, they often are. 27% of Go developers report using Python alongside Go in the same project, behind TypeScript (43%) and just ahead of JavaScript (24%). We know from interviews that the usual division of labor follows each language's strengths: Go for the networked services and infrastructure, Python for data work, machine learning, and anything that depends on the scientific library stack.
13 Oct 2026 1:41pm GMT
Rodrigo Girão Serrão: Sentinel built-in
![]()
Learn how to use the sentinel built-in from Python 3.15 for placeholder values.
Python 3.15 introduced the new sentinel built-in. The sentinel built-in can be used to create placeholder values:
NOTHING = sentinel("NOTHING")
A placeholder created by sentinel is the more idiomatic way to provide default arguments or return values where None wouldn't be usable.
15 days of Python 3.15
To celebrate the release of Python 3.15, over the next 15 business days I'll be writing about a new 3.15 feature every day. Explained clearly and with examples so you don't have to sift through the changelog.
Subscribe to receive this free email series:
If you want, you can also check the schedule of the upcoming emails.
Creating and using sentinels
The built-in sentinel accepts a string argument which is the name of the sentinel:
NOTHING = sentinel("NOTHING")
print(NOTHING) # NOTHING
The name of the sentinel is used as its default string representation.
Alternatively, you can provide a second named argument to be used as the representation of the sentinel:
NOTHING = sentinel("NOTHING", repr="__main__.NOTHING")
print(NOTHING) # __main__.NOTHING
While there's no runtime restriction imposed, the name of the sentinel and the name of the variable that the sentinel is assigned to should match:
# Correct:
NOTHING = sentinel("NOTHING")
# Wrong:
NOTHING = sentinel("nothing")
N = sentinel("NOTHING")
BANANAS = sentinel("APPLES")
Linters and type checkers may complain if there's a mismatch. Since sentinels are typically constants you won't update, it's also common for sentinels to have names in all uppercase.
Sentinels are typically used as placeholders and the most common operation is to check if a value is a specific sentinel. For example, imagine a function find that looks...
13 Oct 2026 1:11pm GMT
Django community aggregator: Community blog posts
`replace()` as an iterator
String.prototype.replace() with a global regular expression and a function has iterated over the interesting parts of a string since 1999, long before array extras like forEach() and filter(). It is rarely the best tool today, but it is still in a lot of code, for historical reasons and for a certain technical beauty. Let's see how it works, what it is good for, and what it costs, so that a replace() whose result goes unused makes sense when we meet it.

13 Oct 2026 10:00am GMT
09 Oct 2026
Django community aggregator: Community blog posts
Issue 358: Django 6.1.2, 6.0.9, and 5.2.18 Security Releases and Djangonaut Space Session 7
News
Django security releases issued: 6.1.2, 6.0.9, and 5.2.18
Four CVEs fixed: denial-of-service risks in language-code lookups and HTTP header parsing, spatial lookups that could make GDAL fetch external rasters, and model formsets with editable primary keys that forged POST data could use to delete or create instances. Raster bytes passed to spatial lookups must now be wrapped in GDALRaster, a backward-incompatible change, so upgrade and check your GIS code.
Welcome to Session 7 Teams 👩🏽🚀
Djangonaut Space Session 7 runs October 12 to December 6 with its biggest cohort yet: 28 Djangonauts picked from 92 applicants, across eight teams working on Django core, accessibility, Django Debug Toolbar, djangoCMS, and the Django Girls+ website, plus two Python projects, BeeWare and Render Engine.
Django Software Foundation
Django security reporting update
Django no longer takes new security reports through HackerOne. Existing HackerOne reports stay open with the Security Team, and new issues should go to security@djangoproject.com as described in the security policy.
Python Software Foundation
Python 3.15.0 candidate 3 is here!
Last-minute lazy-import release blockers earned 3.15 a surprise third release candidate, pushing 3.15.0 final to October 9. Maintainers should test and publish 3.15 wheels now; release candidate wheels will work with the final release.
Wagtail CMS News
Our agent skills for Wagtail developers
Agent-friendly documentation for your Wagtail tasks.
No GSoC on Wagtail core in 2027
A weekly, sometimes daily, flood of low-effort PRs (one fix came "tested" with a screenshot that wasn't even the Wagtail UI) has Wagtail pulling core out of Google Summer of Code 2027. It may still mentor on simpler projects like the user guide and Made with Wagtail, so register interest via the form rather than opening PRs, since nothing is confirmed until March 2027.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! 🚀
Last week we had 13 pull requests merged into Django by 11 different contributors - including 2 first-time contributors! Congratulations to Juliana Nicacio and Max Azatian for having their first commits merged into Django - welcome on board!
News in Django:
- Fixed a bug in Django 6.1 where the
UUID4function persisted uppercase values on Oracle. Any data already created using this function on Oracle should be migrated to lowercase so that it can be queried correctly (#37376). - Fixed a visual regression in Django 6.1 where an extra empty breadcrumb was rendered on the admindocs model index page (#37378)
- Fixed an infinite loop in Django 5.2 in tuple lookups (e.g.
TupleIn) when an F() expression was used as the left-hand side (#37291).
Articles
Django: serve apple-app-site-association and assetlinks.json
Adam Johnson follows his security.txt post with the files that let iOS and Android apps open your site's links (Universal Links and App Links) and use its saved passwords and passkeys. He covers the JSON content types, keeping /admin/ in the browser, caching, tests, and how to check what Apple and Google actually fetch.
Afterthoughts: Django Day Copenhagen 2026
A short post on attending this year's event and giving one of the talks.
Questions to Ask a Company Using Django
The 8 questions to ask any Django-based employer before joining their engineering team.
Building a small Django app with help from AI
Stein Ove Helset builds a small idea board and shows where AI earns its keep: first-draft templates and tests, plus reviewing a working vote view instead of being told to "make this better," which surfaces the race condition in votes += 1 that an F() expression fixes. His rule: treat AI code like a random Stack Overflow answer you are now responsible for, and never paste in real secrets.
How to deploy multiple Django projects on one server
Instead of a server per side project, give each one its own virtualenv and a Gunicorn process on its own local port (8001, 8002, and so on) kept alive by Supervisor, then let Nginx route by server_name. Each project can run a different Django version and database, and adding another is mostly a matter of repeating the steps.
Sponsored
Reach 4,300+ Engaged Django Developers
Sponsor this newsletter to reach an active community of Python and Django developers.
Django Fellow Reports
Django Fellow Report - Natalia
Natalia cleared the untriaged queue (10 tickets), reviewed the Sphinx compatibility changes and fixed related doc references, and reviewed support for Address objects as email addresses. On the security side, she reviewed a confirmed vulnerability and helped Jacob send pre-notifications for the October 6 release.
Django Fellow Report - Jacob
A heads-down week closing release blockers for 6.1.2: Jacob fixed UUID4() persisting uppercase hex on Oracle, filed tickets for JSONField __in lookups on primitives and iterating F("pk") hanging, repaired failing MySQL jobs on Jenkins, and sent the security pre-notifications.
Django Fellow Report - Sarah
From a holiday in Turkey, Sarah still opened PRs to allow multiline template tags and fix the tokenization of raw template blocks, reviewed the PR dropping GDAL 3.3 and 3.4, and worked on two security issues. Her following week was properly off: swimming and Turkish food.
Videos
Django Day Copenhagen 2026
The complete recording is up of this recent full day conference of Django goodness.
Week 6: Django Forms, Generic Views, and Database Interaction
Dr. Chuck Severance follows data from an HTML form to the database and back in this 25-minute course lecture: GET versus POST, CSRF protection, templates, and class-based and generic views, with the object-oriented inheritance behind them. It wraps up the guided tutorials before his students move on to more independent Django work.
Video Tour of Wagtail 8.0
An 11-minute walkthrough centered on version 3 of the Wagtail API, which can now publish, update, and organize content for automated and AI-agent workflows. It also covers custom base page models, the new permission policy registry, Django 6.1 support, and accessibility and image format improvements.
MCP server in Wagtail - experiments demo
A five-minute look at Wagtail's experimental MCP server: an agent built into the CMS, running DeepSeek V4 Flash with 50+ tools and no instructions on how to use them, doing content operations.
Django Job Board
A new junior developer opening at Softechassociate joins Proxify AB's two senior roles, one Python backend and one React/Node fullstack.
Junior Developer at Softechassociate 🆕
Senior Backend Developer (Python) at Proxify AB
Senior Fullstack Developer (React.js / Node.js) at Proxify AB
Projects
justinmayer/django-benchmark/
Django performance benchmark profiler.
derblub/django-upgrade-report
Point it at your lockfile and it asks PyPI which dependencies block your next Django upgrade, then names the smallest safe release for each in order: what to bump today, what has to ship with the Django bump, and what to check by hand. Run it with uvx django-upgrade-report, and use --fail-on to gate CI.
Sponsor Django News
Reach 4,300+ Django developers every Friday. See sponsorship details and rates.
09 Oct 2026 3:00pm GMT
Planet Twisted
Glyph Lefkowitz: Programming Isn’t Special
Creative Work
Writers went on strike to get protections against "AI". Thousands of artists have signed open letters in protest of "AI". There are so many copyright lawsuits from creative industry groups against AI that there's a whole dedicated website for it. Popular YouTubers absolutely hate it. If they're also musicians, they REALLY hate it. Across all creative industries, there is a concerted push to reject this technology.
Yet, almost unique among creative fields, many experienced programmers remain convinced that it's fine to use "AI" for programming. We do seem to hate it, and it's making us all miserable, and what it's doing to our industry, but we are using it anyway.
A lot of the justification of this resignation seems to be to be because programming is not Art. If the tool can get the job done, and the job is just functional, then why does it matter?
It does matter, though. It matters because we shouldn't be using AI to produce Art, and programming is Art.
Art can be Mundane
Some people will say that programs cannot be art because programs are functional, rather than being expressive. Programs are mundane whereas art is transcendent.
This is based on a distorted understanding of what Art actually is.
In John Berger's "Ways of Seeing", he names this type of distortion "mystification". His example of this process is both amusing and illustrative. I encourage you to read it in its entirety.
In summary, though: Berger critiques the florid prose of an art historian describing a commissioned group portrait, including phrases like "subtle modulations of the deep, glowing blacks" and "harmonious fusion". The portrait is described as sublime, in nearly ecstatic terms.
Berger reveals that the reality of this portrait is that a poor old painter needed some work, and some officials probably thought it might be nice to have an official portrait. So they paid some money to the poor old man, and he painted it, and then they had a painting. It's a well-executed portrait of a group of people. Beautiful, even. But it was work commissioned for a fairly mundane purpose and it suited that purpose just fine. It was not, and is not, a divine relic.
Culturally, we are prone to mystifying painting, and sculpture, and film, and music. We imbue them with "subtle modulations". We ignore their functional aspects - we desire decoration, amusement, and distraction - and focus on their emotional impact.
Don't get me wrong: I love me some good aesthetic philosophy. I think it's great to really examine our reactions to artwork and to try and gain a deeper understanding of our culture and our selves through media analysis. If anything we really need to do more of it.
This does not mean that the creation of such works is mystical or that it should be venerated beyond any other sort of labor.
Not least of which other types of labor that are adjacent to, but not as culturally venerated, as fine art. We tend to mystify the work of a novelist, but to denigrate the work of a journalist. In reality, the functional prose of the journalist is no less important and deserves no less respect.
Although they might be far below the ethereal realm that novelists inhabit in our collective imagination, even journalists receive more respect and thus more mystification than lowly copywriters. Yet, there is no transcendental distinction between "novelist" and "copywriter"; the many of the skills are the same, and the distinction is merely an accident of commerce and opportunity.
In fact, many famous writers have famously inhabited both roles. This is not an accident! Working with words professionally, even (perhaps especially) mundane words, is excellent practice for working with words in a more purely artistic context, because even mundane creativity is still artistic.
Code can be Beautiful
One thousand Internet years ago, when I was in my late teens, I would describe myself as a "code poet". I was relentlessly mocked for this as what the Youth would today call "being cringe", and at the time was referred to as "pretentious".
I succumbed to the peer pressure, removed it from my email signature and my bio. While I still believed strongly in the parallels, I accepted that - socially, at least - comparing code to poetry, or indeed to Art, was a silly thing to do.
However, I never abandoned the idea, in my heart.
The thing that I am most well-known for, the invention of Deferred, was specifically an aesthetic reaction to the tedium of passing callback and errback parameters to every single remote procedure call in an RPC client/server application. Those two callbacks got the job done just fine. But they were ugly, and annoying to work with.
Deferred is an intentional poem about asynchronous task execution, with a deliberate eye to the aesthetics of the problem and the experience of using it. It was influential because of its focus on aesthetics.
I do not want to overstate the beauty or profundity of this minor contribution, or indeed its durability. That a poem exists does not mean it is a great poem, merely that it is a poem.
Our aesthetic culture around programs is more like folk epic poetry than fine art, so the influence of this contribution is less about its specific enduring power than it is about its influence on what came next; from MochiKit.Async to JQuery Deferred to JavaScript Promises and eventually to async/await; a long chain of different artisans each adding something of their own until the original has all but dissolved. (And I wasn't the "original" here, either, as I drew heavily from the E language's Promises, among other things.)
In order to make code into a deliberate artistic expression, one must have spent quite a bit of time contemplating the problem domain. Without having experienced the tedium of manually passing a thousand callback parameters, I would have had neither the skill, nor indeed the motivation, to bother creating such a thing.
Now, most code does not have to be like this. Most code does not get to be like this. Most code is functional, workday code. Most code could not make a lady weep. It's just copy-writing, if you will.
As I explained previously, most writing couldn't do that either. Most writing is just copy-writing, too. Most visual art is advertising. Most live music performance is background music in bars that will go largely ignored.
However, code that is intentionally aesthetically designed tends to be important, both socially and technologically.
We do have some tradition of self-mystification in software. As Abelson memorably put it, "Programs must be written for people to read, and only incidentally for machines to execute.", so we have long had some conception of programs as highly expressive, even if we can't always agree on what they're expressing or to whom. We will occasionally wax poetical about the philosophical implications of a particular piece of software. This is not unique to a single piece of software, either; more than one community has indulged in similar philosophizing.
The expressive and aesthetic qualities of software are not limited to reading source code or interacting with other programmers via APIs, either. For example, every year, Federico Viticci does a review of Apple's new operating system, which is (among other things) an aesthetic critique. Such a project would not be possible if the software did not have an aesthetic impact on its users.
Not to mention that every video game review is also a software review.
A Brief Aside about Software Literacy
It does make me a bit sad that we don't have much of a critical reading tradition in the software community. Literate Programming is often praised, but rarely practiced.
Moreover, it makes me sad that users have a pretty jumbled idea of what goes into making software, that programming literacy is pretty low, and that modern programming practices often deliberately produce a bad mental model of what the software is doing so it's even harder for the user to understand. The aesthetic experience of software is often wildly detached from its internal state.
While all of these problems predate AI by years or indeed decades, that's no reason to enthusiastically make them worse.
Defend The Mundane
If we use AI to erase all the copy-writing, all the graphic design, all the boring mundane art, and yes, all the boring custom WordPress theme development, then we will be removing all the practical opportunities for the vast amounts of practice and contemplation required for people to elevate their craft to eventually achieve great things. Education is great, but the majority of true skill development happens on the job and always has.
This doesn't mean that we can't use abstractions, or automation, to make our work easier. Programming is the art of abstraction, of understanding how to compose smaller ideas into bigger ones, of how to understand the automation of a larger system by understanding the rules that automate smaller ones and understanding how to combine them.
When we use "AI" to eliminate that understanding rather than raise it up to a higher level, to entirely destroy that creative decision-making process, we do a disservice both to ourselves as programmers and to our users. We would be doing a disservice to our users and our downstream fellow developers in the same way that a visual artist would be doing a disservice to their viewers or a musician would be doing a disservice to their listeners if they served them auto-generated filler instead of their own creative output.
Slop is slop, no matter the medium.
Each mundane project has some tiny chance - let's say, something like 0.1% - of achieving greatness. If we do a single project with AI, then sure, whatever, there's almost no chance that that project was going to be the one hit to create that career-defining moment for an engineer working on it. If we make a habit of doing all projects that way, though, we take the total likelihood of those moments of greatness from "definitely sometimes" to "never".
The precisely appropriate ways in which to resist AI encroachment on all software development lie well beyond the margins of this one short post. How much you can resist and which specific uses you should resist are up to you. But it is worth resisting in software just as much as it would be worth resisting in any creative medium.
Programming isn't special. It's just Art, and Art is the most human - and thus, the most universal - thing that there is.
Acknowledgments
Thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor!
09 Oct 2026 7:00am GMT
08 Oct 2026
Django community aggregator: Community blog posts
Django: set up its test suite with uv
When contributing to Django, you'll want to run its test suite to check your changes. The official contributing docs cover setup in Running the unit tests, using a virtual environment and pip. Here's an alternative guide using uv.
Setup
First, clone Django and change into the repository:
$ git clone https://github.com/django/django
$ cd django
(You can fork it later if you want to make a pull request.)
Then, create a virtual environment:
$ uv venv
Using CPython 3.14.6
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
uv automatically picks a compatible Python version for you, downloading one if needed.
Next, install Django in editable mode, plus the test requirements, in one command:
$ uv pip install -e . -r tests/requirements/py3.txt
uv pip automatically targets the .venv directory, so there's no need to activate it first.
Run the tests
Activate the virtual environment, change into the tests directory, and run runtests.py:
$ source .venv/bin/activate
$ cd tests
$ ./runtests.py
Testing against Django installed in '/.../django/django' with up to 8 processes
...
Skip pylibmc if it won't build
The test requirements include pylibmc, a memcached client that wraps the libmemcached C library. In my experience, it's the biggest sticking point when setting up Django's test suite, as installing pylibmc means compiling it, which means you need a C compiler and libmemcached's headers correctly installed. If the compilation fails, you'll see an error like:
src/_pylibmcmodule.h:42:10: fatal error: libmemcached/memcached.h: No such file or directory
Rather than fixing the environment, it's often easier to skip installing pylibmc entirely. This is safe because Django will skip any tests that require pylibmc, so you can still run the rest of the test suite.
The official docs suggest commenting out pylibmc's line in requirements/py3.txt, but that leaves you with a modified file to avoid committing. Instead, filter it out on the fly with grep -v and shell process substitution:
$ uv pip install -e . -r <(grep -v pylibmc tests/requirements/py3.txt)
Then run the tests as above, and Django will skip any that need pylibmc.
08 Oct 2026 4:00am GMT
28 Sep 2026
Planet Twisted
Glyph Lefkowitz: What Would A Serious AI Product Look Like?
One of the issues that I have with the current generation of "AI" products is that they do not appear to take their own premises seriously. I look at a plethora of obsequious chatbots claiming to be serious tools for problem solving, and I think, this is not what a problem-solving tool would look like.
Even before we get to the tremendous ethical problems with the frontier labs, it is this impression of their composition as a product that makes me feel, constantly, whenever I am interacting with them, that they are less a software product than that they are a grift, a scam designed to make me feel like I am interacting with a product that has capabilities that it simply does not, to try to lull me into a false sense of security that I can trust it.
The frontier labs are of course the worst offenders, but every criticism here applies just as much to Ollama, which (if anything, due to the obviously poorer quality of the available models themselves) needs these features even more than the frontier labs do.
Here, I will set down a few features that might convince me that an LLM-based product, particularly one focused on research or software development, was actually serious about helping me do useful things with it.
Make "Checking For Mistakes" A First-Class Feature
This is the biggest issue, and the major reason that I was inspired to write this post.
It is a truth universally acknowledged, that AIs cannot reliably provide information.
I could cite a ton of news articles and studies about this fact, but there is no need. Every single chatbot admits this, up front, in a fine-print disclaimer as a core part of their user interface. Gemini says "AI can make mistakes, so double-check responses", Claude says "Claude is AI and can make mistakes. Please double-check responses.1" ChatGPT says "ChatGPT can make mistakes. Check important info.".
Every time I see that last one, I wonder how I'm supposed to know what "info" is supposed to be "important".
All of these warnings are all small, gray text, painfully obviously included as legalese to push responsibility back onto the user rather than to help with anything. This is a core limitation of all these products. Checking their output is a part of the workflow for using them that:
- you absolutely cannot skip or skimp on without creating risks to yourself and whoever you are conveying its output to, and,
- it is very easy to skip or skimp on and you are encouraged at every turn to do so, because "just trust the output" is one of the quickest ways to save time.
A chatbot product that took this weakness seriously, as an actual consideration for using it, would put a checkbox next to every claim in its output. It would be a 2-column worksheet, where you've got the LLM output in the first column, and next to it, human notes in the second column, explaining what work went into checking this claim, and a big checkbox that you would only check off after you believe you'd checked its claims thoroughly enough.
Coding assistants would need to have some version of this as well. Right now, this is pushed off into code review, which means it is a dark pattern which subtly encourages the "author"2 to offload this work to their code reviewer without ever looking. Once again, "it's probably fine, I don't need to check" is the quickest way to save time and churn out those PRs faster.
It might even be useful for coding harnesses to have some affordance for checking code before it even runs tests. As the vendors themselves have admitted, it's not just expensive to burn tokens on your "AI", you also end up burning far more compute on the AI. Being able to check your diffs before sending them over to uselessly exhaust your testing compute cluster would be useful.
If your product tells me that it makes mistakes and I must be the one to check for the mistakes, but then gives me zero tools to check for mistakes, I cannot take it seriously.
More Citations to Check, And More Details
Most chatbots prefer to give an answer, rather than a citation. In my own personal use, I find that when asked to provide a list of citations with clearly marked sources for each one, they will appear to "get bored" halfway through the list and simply stop including citations at some point.
When the bots include citations at all, present them as inline annotations that say nothing but the domain name of the search result, in a font so small that it's barely legible, and an equally indecipherable icon that is fewer than 16 pixels on a side.
This is backwards.
Now, I am aware that these citations do come from somewhere, and in an attempt to reduce hallucinations, all of the major providers support some form of "grounding"3, and that those little barely-readable citation links are referencing actual structures in the RAG pipeline and not just potentially-hallucinated tokens, but I'm not talking about the underlying machinery in the model, I'm talking about the presentation to the user.
Plus, regardless of whether a snippet of text came from a RAG query, we know that LLMs can never provide an authoritative result; it's a fundamental limitation of the technology. They can still garble the results of RAG as much as they can misrepresent any other training data. This means that it must never present its results as authoritative.
If you ask an AI to do research queries, every result should be presented as a list of citations. Moreover, the presentation should display each citation as a large object of in its own right, with clearly identified metadata, including not just the site where it was found but its publication date and, if possible, the name of the author. The literal, unmodified quotation (not from RAG, not a summary: a quotation extracted with a regular program and not an LLM) should be front-and-center, larger than any AI-generated text.
If the AI product wants to editorialize or summarize (which should not always be necessary!), the AI-generated text should be presented as small text underneath the citation that has been found, de-emphasized as much as the disclaimer is right now, at the very least until the user has verified that the summary is accurate. Perhaps, for a research project, a "did you read the citation" checkbox might even be helpful.
If your product openly tells me that it will scramble, misrepresent, or omit its citations in its summaries, and I must read the original human-authored citations to be sure, but then gives me no tools to track my reading of those citations or even any way to find them, I cannot take it seriously.
No First-Person Output, No Apologies
There is no reason for a software development or research tool to use first-person language to describe itself. They should not do so. In fact they should not be allowed to do so.
There is also no reason that they should ever apologize. It is a waste of everyone's time; it's a waste for the chatbot to generate the apology, it's a waste for the user to read the apology, and it's a waste for the user to respond to the apology. Yet they unfailingly do this upon every correction.
The vendors of these tools know that they are routinely causing mental-health crises. In response, they have added non-functional "guard rails" that can still, in 2026, easily be bypassed.4
A product seriously interested in helping with productivity would correct this glaringly obvious flaw, focus on the task at hand, and stop emitting useless verbiage.
In the previous two sections, I tried to focus on ways in which the harness would be constructed differently even if the LLM technology is fundamentally impossible to improve; in this case, I have to assume that the labs have some control over the model itself. But unless they are truly incapable of influencing their output (and all their "benchmarks" and "capabilities" seem to indicate that they can control it very tightly) they ought to be building models that are much less verbose.
More Non-Natural-Language User Interfaces
Although natural language could hypothetically be a powerful interface for interacting with a computer system, the practical upshot of LLM natural language interfaces is that these interfaces are imprecise and repetitive, full of superstitions masquerading as "best practices". The inputs are a mess and the resulting outputs are a mess.
The general way of addressing this unstructured mess is to allow the chatbot to directly take action in response to the user's input; in other words to supply it with "tools" via an MCP server. But again, this is backwards. If we cannot even express our intent clearly in the first place, why are we trusting this system to take potentially destructive and harmful actions on our behalf?
Instead, I would expect a product that was seriously invested in helping me accomplish specific tasks, to have user interfaces specific to those tasks. Is it supposed to be able to be a security scanner that can discover OWASP top 10 bugs in a codebase? Have a button for that. Build that functionality into your harness, train it directly into the model, use smaller models that can satisfy that functionality more effectively than throwing it at the planet-sized brain of Fable or whatever.
I'm aware that there are small software startups that do something like this, but they are bolted on to the side of the main model providers' APIs, not integrated into the core of the product and not using their own models and AI systems to achieve consistent and repeatable results.
Strong Data Provenance Indicators
Chatbots produce data tables pulled from websites, from APIs, from MCP tools or from summarizing and scrambling the user's input. In order to provide the illusion of a seamless interface, this data is presented in-line regardless of where it comes from. But some of these outputs are produced mechanically via regular old API calls, for example, from the result of calling a tool or querying a website, but presented uniformly.
But there is a huge difference between an authoritative data source being inlined as part of a chatbot conversation, being treated as input by the chatbot, and some ad-hoc hallucinated data being treated as output of the chatbot.
If a product is trying to help me make accurate, empirically-grounded, data-driven decisions, the source of the data is critical.
Integrated into the "check for mistakes" and "verify citations" workflow I described above, there's a necessary "verify data programmatically" pass as well; to have tools that will treat portions of the output as a regular spreadsheet, allowing regular-old computer arithmetic to verify things and showing where such arithmetic was used, and how.
Better User Control of Reproducibility
Anyone familiar with the technical specifics of LLMs will know that they have a variable called "temperature" which controls the degree of randomness that the LLM uses to produce its outputs. But most users don't know this, because it isn't exposed as part of the user interface by default.
This leads to a subjective impression that you asked ChatGPT, and you got ChatGPT's authoritative answer.
You can't just set the temperature to zero and still get useful results - I am aware that it does more than just scramble the output at random, and there are perhaps good reasons that simply exposing just a temperature setting would not be that useful to users. But if we followed some more of my earlier recommendations for making more structured UI elements to solve specific problems rather than having long back-and-forth chats where each refinement depends on the previous response, perhaps those elements could also re-play the process so that users can see how reliable the bot is at a particular task and develop a sense of how the stochastic nature of the process actually affects it.
Similarly, if a user is trying to solve the same problem repeatedly with a chatbot, and the chatbot product has numerous computational tools that don't really have anything to do with the LLM, such as deterministic data-processing tools, then having a way to freeze the non-deterministic parts of the transcript but re-populate a particular data frame with updated information and fork / continue the conversation from there would be a way to avoid introducing pointless additional randomness when you already know what tool you're trying to use.
The fact that every conversation is presented as this flat chat prompt that doesn't let me interact with any of the widgets that were previously produced except through more chatting, really makes me feel like the whole product is just doing predatory social-media style "increase time on site" optimization, just trying to lure me into further repetitive and unreliable chats, rather than letting me get in, solve my problem, and get out.
Context Visibility
Managing the LLM context is the ongoing challenge facing organizations that are trying to use "agentic" workflows. Filling up the context with too much information causes well-known problems. In response, advanced LLM users attempting to solve larger problems must break up very long prompts into "skills", give access to lengthy information via "tools", and delegating sub-problems to "sub-agents" rather than simply extending a single prompt indefinitely.
All of these strategies have flaws, because even on the largest models, compared to the breadth and depth of knowledge-work problems, LLM contexts are quite small.
And yet, none of these products will show the context to the user by default. There are third-party addons that can show you a simple progress bar but for addressing the premier engineering difficulty with this technology, that is below the bare minimum.
This lack of visibility means that almost all of the tools for extending the context are flying blind. Rather than responding meaningfully to a full context, everyone just kind of guesses how much state they need by guessing and trying over and over again with progressively more elaborate skill and sub-agent layouts. Even managing context compaction ends up being an advanced API-driven workflow5.
A serious product that was trying to help the user understand would not only show "available context" but explain the impact of context compactions, make it easier to see harness-generated prompts, and so on. This would be a first-class feature, combined with the aforementioned reproducibility / replay tools, would allow users to do real experiments to develop an understanding about how to make good use of the context window.
A Sandbox That Actually Works
I've been focused on the chatbot interface here because it is the most immediately egregious upon looking at the UI. But the "agentic loop" tools used for coding are equally dangerous, if not more so. Coding tools keep destroying everyone's data, over the course of years.
These catastrophic incidents that become front-page news are relatively rare compared to the amount of coding-agent use out there. But they also aren't the only kind of sandbox violation. Coding models will so routinely edit test code instead of the system under test that there are "pro tips" articles all over the web giving you the flawed advice to simply ask the agent not to cheat. News write-ups of the catastrophic incidents themselves will also offer glib and wrong advice, like "use a docker container". That might prevent it from literally deleting your operating system, but it won't prevent it from destroying all the local work you have in your codebase (it needs access to a checkout, after all!)
There is a flurry of activity in the infosec space where people are rushing to plug the gaps left by these coding harnesses. Everyone's got their own version of an MCP approval gateway where you can optionally place a proxy between your agent and your production infrastructure.
In the best case, though, all these mitigations and proxies and prompts simply turn the user into an auto-approval automaton, hitting Y, Y, Y, Y over and over again, until you finally are driven mad and hit "yes to all", turn on full-auto mode and submit yourself to the void. With nothing between your personal vigilance and disaster, there are no workflows left beyond decrementing your own vigilance until there's nothing left and then hoping the disaster never arrives.
The fact that some mitigations exist that can be deployed by extra-cautious users does not change the fact that "agentic coding" is an unsafe-by-default technology deployed without concern or guidance. Every frontier lab has tied a spring-loaded shotgun to a dog; the fact that dog owners can publish thoughtful blog posts explaining how you can teach your dog the basics of gun safety or how you can have your dogs play in a bullet-proof room does not mitigate the fact that the product should not have been allowed in the first place, nor should it continue to exist without VERY strong security controls.
I might believe that a frontier lab were seriously interested in providing developers with a useful tool if they shipped something that had safety built-in.
That means tools in the harness, detached from any LLM, independent of the prompt, that could:
- sandbox all filesystem operations and strictly limit ANY deletions outside of specified scopes, regardless of operating system,
- enforce snapshotting of the entire repo on every operation for easy rollbacks and minimal lost work,
- remove the disaster of "auto mode" (not to mention nonsense like
--dangerously-skip-permissions) entirely, and - carefully consider a structure for presenting plans to the user where, rather than provoking immediate alert fatigue by asking for checks on every action, make structured plans which can be submitted to the user as a group of actions and reviewed and approved as a batch.
In the same way that I suggested above that research-based tasks should have a way of re-issuing prompts to determine how reproducible a result is, or whether other sources might be found, agent-based tasks should have a way of being executed against mock services for popular APIs, so that the verification can match both on the front-end (review the plan for making the API calls before they're executed) and the back end (review the API calls that were issued to the mock service and verify that they matched).
Instead, the frontier labs provide us products that are disasters out of the box, give us "best practices" to build massive and elaborate, as well as incomplete and error-prone, security perimeters of our own design. Then they blame "operator error" when it inevitably goes wrong. I cannot believe that these design choices are intended to help us be productive.
Bonus: Human Processes
Organizations deploying AI also frequently come across as unserious, for similar reasons. In 2023, naive exuberance could perhaps be forgiven. But today, as we near the close of 2026, there are several well-known problems, that have been extremely well-covered in the press. None of these things should be surprising, but most orgs deploying these tools are still just letting them rip and hoping it all works out.
Organizations deploying these tools would need at least three kinds of major modifications to their internal processes, if they wanted to be serious about using them safely:
1. Shift Rotations to Prevent Vigilance Decrement
There have been several high-profile incidents where software developers' gradual acquiescence to accepting LLM output have lead to serious economic consequences for the companies deploying them, perhaps best typified by Amazon's "millions of lost orders" due to a gradual decay of their engineering processes from LLM use.
These outages, and other AI-related failures, are due to the difficulty of maintaining focus on the same problems. In other words, as I described above, vigilance decrement is a constant problem, because AI outputs are most often correct, but continue to be incorrect in surprising and non-intuitive ways. As I have previously written, you cannot trust yourself to catch every bug with code review, and LLM output.
Aviation, for example, has very strict rules around rest requirements. There is also a specific rule that "No certificate holder may operate an aircraft without a second in command if that aircraft has a passenger seating configuration, excluding any pilot seat, of ten seats or more.". Other safety-critical professions have similar rules.
And yet, even in the age of the supposed "AI revolution", most software teams are still assigning every engineer a full feature load, not planning for any rest, and telling people to review code whenever they happen to have some "free time".
Maintenance of vigilance has to be your top priority. Regular, scheduled, inviolable rest periods where people do work without AI assistance, and are not exposed to any AI output for review or otherwise, would be crucial in order to stay mentally sharp enough.
The tools themselves should have this sort of thing built in. The mistake-review process described above should have a periodic spot-check mode where a second reviewer periodically reviews a chatbot log, doing their own independent verification of claims, to see if they spot the same errors. This could provide a feedback loop to determine how much rest is necessary to maintain continuous attention and actually spot hallucinations.
2. Skill Practice To Prevent Skill Loss
It is also well-known that AI use leads to AI reliance, and AI reliance leads to skill loss.
I like to use the analogy to dockworkers at a seaport6 adopting automation.
If you employ dockworkers to load and unload ships all day long, they are going to be getting tons of exercise. They will be able to lift heavy objects on demand, whenever. They might have plenty of health problems and injuries from this type of work, but "lack of exercise" will not be a problem.
With the development of standardized container ships and mechanized cranes, you are going to be changing their job description substantially: now they mostly spend all day sitting in a small cubicle moving a control lever back and forth, not lifting heavy stuff. They will get worse at lifting heavy objects.
In this analogy however, the cranes are not all that reliable. We know they break, and they drop their payloads sometimes, and the stuff needs to be manually moved. But this only happens a few times a week, at most. If you need whoever is driving the crane to be able to jump out at any moment and still move stuff around manually, then you need to make an affordance for that. You need to give them time to go to the gym and do some lifting for practice, or every crane failure is going to be a major emergency.
An organization doing an AI transformation would also need a massive increase to learning & development budget, both in terms of resources and in terms of schedule. If your people are going to lose skills because they've lost regular practice in the incidental course of doing their duties, then they are going to need deliberate, intentional, non-incidental practice of those skills to keep them sharp.
But rather than trying to accommodate new workflows and give time for people to adjust, most AI mandates are simply dropped on workers like a ton of bricks, with no time to adapt and no affordance for maintaining their skills. Operate the crane and stay fit and healthy and ready to switch back to manual lifting at any time and then get back in the crane cockpit right afterwards. Don't mess up.
Then an accident happens and everyone is surprised, as if this process weren't practically designed to produce a terrible result.
3. Mental Health Resources to Deal with Mental Health Risks
AI psychosis often begins with practical problem-solving, and beyond that, it can start specifically at work. Not to mention the more pedestrian condition of "AI brain fry".
If you are mandating your employees to use a hazardous tool that may seriously and directly damage their mental health, you need trainings and resources. You need in-house therapists and you need to be making sure to check in with people actively to make sure that this is not happening.
Again, the tool itself ought to have some way of dealing with this. An occasional "take a break" popup is easily dismissed; they need a user-visible AI personal dosimeter so you can see your cumulative usage over time.
I don't even know if "usage over time" is a sufficient metric to gauge risk. Maybe if your work chatbot start to talk about resonance too much, unless you literally work as an acoustic engineer, that should be flagged for someone.
We are, again, years into dealing with these tools, and we know these risks exist. Yet no serious mitigations are provided. Not even any way of measuring the risk exposure.
And More
There are also many other risks associated with the technology. There are intellectual property risks with the foundation models, due to recklessness with their training data. There are existential financial risks associated with the infrastructure build-out. The extent to which most "open" models are simply derivatives of frontier models is an open question.
What I Think
If any one of these things were regularly overlooked by AI vendors or users, that would be a totally normal product oversight. Room for improvement for the next version, but nothing catastrophic.
Shipping without any of them doesn't seem like lean product management, it seems like a careless attitude towards risk and a product design philosophy oriented entirely towards short-term demos, with no regard for how to realize actual productivity gains.
Furthermore, being available for years without anything like these features, despite hundreds of incidents demonstrating the risks, with hundreds of billions of dollars of funding, makes it seem to me like if they were to add all the features that would make their product actually safe and hypothetically useful, these features would reveal that it is actually not an improvement to productivity.
In the year since I first wrote about measuring the cost/benefit ratio of AI, I have heard from numerous people who have shown this to management to try to illustrate why their AI initiatives - like almost all AI initiatives - were either failing or burning out their engineers.
I've also heard from lots of people that have told me that it's obviously useful and they don't need to measure so carefully, because they are getting lots of work done that they couldn't have otherwise.7
I have yet to hear from a single person who has said "yeah, we measured according to your methodology8, and it turns out that our AI work is going great and that our ratio is 0.75".
Obviously, I cannot say for sure why this is; absence of evidence is not evidence of absence. But at this point I think the null hypothesis is that AI tools provide, in aggregate, zero value. They make mistakes too often, and the externalities they produce are so bad and so difficult to control that even before we get to the places where they are just physically poisoning people, even the negative effects on their direct users end up cancelling out whatever benefit to they provide to their organizations.
If I were wrong, then including tools to measure an AI's effectiveness at the tasks their users are actually trying to accomplish, rather than meaningless benchmarks, would show big productivity gains. The frontier labs would be champing at the bit to add such features, and crowing about their fantastic results.
I think the labs know that if they did that, it would present a grim picture to their users. Such tools would let their users see that it's making mistakes much more often than they realized, that they're spending much more time with it than they want to be, and that it's just generally not fit for purpose.
If they prove me wrong by adding in all of these safety mechanisms, and in the process, they make all of their AI technology less harmful, I'll be thrilled to be debunked.
Acknowledgments
Thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor!
-
It is also interesting that for the next section, sometimes it seems that Claude's disclaimer is "Please double-check cited sources." instead. ↩
-
... by which I mean the "prompter", since authorship is not what's happening here. ↩
-
Claude has the "citations API", Google has various different kinds of "grounding" against its own APIs, and I guess Microsoft can check OpenAI's homework if you want. ↩
-
Given the relatively slow speed of the justice system and the mainstream press around the world, we probably will not hear about whether people are managing to incidentally break through these guard rails to self harm right now, but there are no shortage of stories still being reported right now where people were still doing just that, such as in this story where the effect of the much vaunted "guard rails" in 2025 was that if you wanted it to write you a suicide note, it would refuse twice but acquiesce on the third try. I don't see any reason to believe this fundamental issue has been addressed in the meanwhile, since it had been happening for years at that point. ↩
-
In this tutorial we can also see an incredibly rosy scenario presented, where a long-running workflow effortlessly compresses all of the necessary information into the new context, even if it uses a lower-fidelity model to do so, rather than the tangled and gnarly problem of problems which really are too big to fit in the context, which is to say, "most real-world problems". This presents the context limit instead as a minor speedbump to be worked around rather than the fundamental flaw in LLM tooling. ↩
-
A heavily fictionalized seaport. This is not how actual dockworkers work. This is a simplistic metaphor about incidental benefits of instrumental tasks, it is not supposed to delve deeply into the mechanics of maritime shipping. In particular I know that cranes are more reliable than this and this is not actually how you would respond to a crane malfunction anyway. Feel free to share fun facts about maritime shipping if that is your special interest but please do not @ me to correct this metaphor. ↩
-
To my knowledge, none of their publicly-traded employers have posted a measurable improvement to efficiency outside the margin of error. ↩
-
Or any similar methodology. I don't need people to adopt the exact practice that I proposed there. ↩
28 Sep 2026 4:27am GMT
25 Sep 2026
Planet Twisted
Glyph Lefkowitz: Who Is Open Source About?
Open source is, at least in part, about you, where "you" refers to the user.
Open Source Is Not About "Open Source Is Not About You"
In other words: Rich Hickey was wrong when he wrote "Open Source Is Not About You" and I'm tired of pretending otherwise.
Of course he's not completely wrong, or his famous post would not have resonated quite so much in the first place. Obnoxious users who demand their personal use-cases be immediately addressed by volunteer maintainers for free should indeed be viewed as the pariahs that they are. Similarly, corporate users who want free support from the community that supplies their infrastructure to lower their costs. As should those who profit from this type of externalization by their own customers.
But the exchange of "open source" (or even "free software") is not as simple as "I have prepared some software for you, please enjoy it, you have no right to complain", and maintainers ought to have a precise understanding of the costs and benefits - as well as the ethical implications - of that exchange.
Right now we barely even articulate that the exchange exists, let alone that it establishes a long-term, subtle, and implicit relationship between maintainer and user.
Let's fix that.
A Brief Aside about Meta-Ethics
When we talk about "obligations" and "rights", of "shoulds" and "musts", we are constructing an ethical system. The purpose of such a system is to develop social expectations and social consequences. There is not much use in me telling you that you are transcendentally evil for failing to follow some arbitrary recommendation that I have. But I am implying that I believe there should be consequences for your behavior. I am also implying that there probably already are some consequences, and they're just not written down anywhere yet.
Therefore, a post like this, where I say that we should view our social obligations in a certain way, that is the beginning of a broader social conversation. I think there should be some consequences, so I am gesturing towards that possibility. Exactly what consequences?
For now, I'm not sure. Let's figure it out.
What Are We Doing When We Do An Open Source?
Hickey, and his many acolytes in the years since his fateful post, asserts that the process of "open source" goes like this:
- Maintainer makes a thing, and makes it available to users as a gift.
- Maintainer may "love working with the team".
- Maintainer may be "proud of the work we do".
- Users accept the gift, and extract utility from it.
- (Users MUST be grateful for this.)
- A tiny fraction of users reciprocally contribute to the thing.
- (Maintainers may be grateful for this.)
He makes various oblique references to the specific activities of his company, which does things vaguely related to his projects for money1. These activities are exclusively characterized as for "customers", however, a subset of the aforementioned users so tiny ("fewer than 1%") as to nearly be an entirely distinct group.
Breezing past this process in an essay about obnoxious users demanding things they are not entitled to, one might nod along, as this sounds mostly sensible. Giving gifts is nice. I too love working with good teams and taking pride in things.
Examined more closely, however, it starts to logically fall apart. If you have consulting clients and that's where all of your money is coming from, why are you bothering (as he repeatedly insists) "doing [things] for the community"? What was the point of releasing this code in the first place? You could love working with your team and be proud of the work that you do in a lot of different contexts; why bother implicating this horde of entitled and obnoxious people, if that's all you're getting out of it? What's in it for you?
If we've left out something as fundamental as "why is the maintainer doing this", perhaps this story leaves out some other important bits as well.
Why Are You Doing This?
There are many possible motivations for releasing and maintaining open source software. They are often subtle, often overlapping, and rarely clearly stated. Maintainers are not a monolith and not everyone does it for similar reasons. But let's review a few reasons that someone might want to contribute.
Reputation
One reason that you might want to release some open source software is advertising. The most common form of this is self-promotion; if you are a visible, prominent contributor to an open source project, it stands to reason that you will have an easier time finding work in the domain of that project.
If you operate a consultancy, as Rich Hickey did at the time of his famous rant, then this reputational currency translates into advertising for your services. It's a practical demonstration of the skills of your team.
The trade in this benefit is most like the traditional "gift economy" that open source has been compared to. You give the code to your users, which has some value, but the users give you back some reputation, in the form of their attention, their esteem, and possibly even their money if they become customers or employers.
Influence
Infrastructure is the most popular type of open source for a good reason. Programmers working on a problem are often hemmed in by sclerotic architectural choices which prevent them from solving problems in the way that they'd prefer to solve them. Major infrastructural investments are difficult to justify in a planning process, as their benefits are hard to prove. Sometimes the benefits are highly personal; different engineers have different aesthetic preferences about what types of equally-valid solutions they'd prefer to work with.
If you can develop your preferred type of solution and release it as open source, then you can influence how everyone else solves this type of problem. As an individual, such a position of influence can allow you to have some transferable expertise between employers. You know how to use the tool you developed, so you can be very quick and effective with it, and you can shape it to your ongoing taste over time.
If you're an employer, and you can get everyone else to use your open source thing2, this can reduce both your hiring and training costs. Potential employees can read the code, see that it's good, and want to work at a place that produces good code like that. They can also read the code and become familiar with it in advance of coming to work for you, which means that you have a ready supply of developers who already know how your internal systems work.
The trade in this benefit is more like "soft power" than a gift economy. You give the code to your users, which has some value, but the users give you back the ability to dictate their technological agenda. You gain both the ability to influence their initial direction, and, as part of ongoing maintenance, to dictate their behavior over time.
Improvement
As an engineer, you might want to improve your own skills. Writing something proprietary and commercial cuts against this in two ways.
First, you will want to build something that already exists within your skill set, so that it will attract commercial interest and actually be competitive. Within the context of a larger team, you will want to personally be able to be immediately effective for similar reasons. But you still need a way to learn new things.
Second, you will want to build something somewhat secretively, so that the value you are producing is captured rather than released to the community. This means that you will be cut off from external sources of expert feedback.
As an organization, you might want to build the skills of your staff in similar ways.
The trade in this benefit is code for knowledge. You release the code or changes, and in return you expect your users to provide you good bug reports, and to induce at least some of them to become co-developers.
Outsourcing
As an engineer, you can only do so much on your own. Perhaps you want to have some influence over your infrastructure so you want to write it, but you also want to have a communal place to keep your infrastructure such that you can make a change to something to suit your needs, but you know that even if you walk away, someone else will maintain that change and keep it working across years or even decades of changes to underlying platforms, hardware, etc.
This sort of communal maintenance effort can be shared among all interested participants; if a thousand companies all need the same tool, if even a few dozen can share it, that reduces even their own load massively, let alone everyone else's.
The trade in this benefit is more complex, since there's less symmetry between the main maintainer and peripheral community members who also contribute code. The main maintainer is actually trading a namespace, a central place for people to contribute, coordinate, and release changes, rather than the code. They are a sort of market maker where then all the other contributors trade code for code within that market-ish structure.
In practice, this motivation produces a game theory problem where, when maintenance drops below a critical threshold, it creates a big enough crisis that at least some freeloading stakeholders will be forced to start making contributions.
Ultimately, however, this saves all involved parties a ton on maintenance, more eager volunteers who do not freeload in the first place get all the other benefits mentioned above as well.
A Brief Aside about your Chart of Accounts
Most companies account for open source maintenance work as simple overhead on ongoing projects. Sometimes it's CapEx, sometimes it's OpEx, but it's just "whoever happens to be working on this thing to support whatever random product it's a part of".
This type of accounting creates distorting incentives, because it doesn't recognize all the benefits above. Under such a fiscal regime, ongoing healthy maintenance becomes a ZIRP because when resources are more constrained, this apparent indulgence gets corrected.
The ancillary benefits that open source creates ought to be properly recognized. It shouldn't just be buried as Wages or IT or whatever. If it's helping you hire better engineers, some of that expense should be allocated to Recruitment Costs. If it's materially improving your reputation among your customer base, some of it should go to Goodwill. If it's getting your product in front of developers who are your customers, it should be in Marketing. Most importantly, if maintenance on an open source project is actually helping you maintain your enterprise-wide platform, it should not be squirreled away in some small team who happened to be the first one to adopt it.3
Exactly how these costs should be allocated and cross-charged to different departments depends heavily upon your organization and your specific chart of accounts. But "whatever, it's just part of the software product" or "I guess it's DevRel because the SDK is in there" is guaranteed to have your open source organization destroyed along with all those side-benefits the next time that there's a cash crunch.
The Things that Aren't Supposed To Be Benefits
These categories could be made as explicit, rational trade-offs, even if they are often implicit and subtle in practice. They are transactions where the maintainer gets something and the user gets something.
However, not everything that you are getting as a maintainer is something you are actually supposed to use to your own benefit. Being given trust in service of a responsibility is not a transaction.
"Oops, All Root Shells"
Open source code is code. In our modern world of absolutely pathetic sandboxing, installing code from somebody else gives them control over your system, even if it is somewhat indirect.
There is an unwritten rule that if I create an open source library, and you use it, it probably shouldn't have a backdoor in it that gives me the credentials to your bank account. There is a trust relationship between the user and the maintainer, and here, we see the first obligation that the maintainer has. The maintainer is obligated not to use the user's computer for their own gain.
This rule might seem obvious and straightforward. It might even seem unfair to you that I call the rule "unwritten", because the rule is, in fact, written down in a few places: for example, in the npm Acceptable Content Policy, it says right there:
A few examples of unacceptable content:
…
- Content containing malicious computer code, such as computer viruses, computer worms, rootkits, back doors, or spyware. This includes content submitted for research purposes. Tools designed and documented explicitly to assist in security research are acceptable, but exploits and malware that use the npm registry as a deployment or delivery vector are not.
I think we can all agree that a script which steals your bank credentials and sends them to me to buy a totally sick jet ski would qualify as "malware", so clearly that is forbidden.
There is also an enormous gray area here. npm also explicitly allows "Information on how to pay, donate to, and otherwise support Package development", but then goes on to explicitly forbid "Packages that display ads at runtime, on installation, or at other stages of the software development lifecycle, such as via npm scripts."4 How are the lines drawn around these gray areas? "npm will continue to apply its judgment when deciding what content is acceptable."
But also... this is forbidden by npm, not by the transcendental nature of "open source". I could give away code that displays all kinds of ads to its users as a "gift" on my website. The exact structure of this policy is not uncommon, but it also isn't exactly the same as other such sites. PyPI, for example, explicitly bans "cryptocurrency mining", which NPM does not. Is cryptocurrency mining "not open source"? A lot of judgement calls are happening here about what is allowable in these "gifts" that you are giving to your users.
But I digress.
My point is that policy-making around this concept is not clear, there are lots of little disagreements around the edges, but there is a very strong consensus that while the user is giving you their trust here, that is not a trade. The deal is not "you give the user some code, the user gives you unlimited compute and access to all their financial accounts". The user has made themselves vulnerable to your code on the strength of your reputation.
This creates an obligation for you to not do anything evil with that code, either intentionally or through negligence.
Security Updates Are Just Command And Control In A Funny Hat
All of this is just about the initial download of some code, and that is the way that Rich Hickey describes it, as if you just grabbed some code off a web page and put it in a folder that you like on your desktop. But that is not how open source relationships work today, if indeed it ever was.
The way it works today is that you add a dependency to your pyproject.toml or your package.json or your Cargo.toml and now your users are vulnerable not just to whatever you happened to upload in the first place, but to whoever happens to have your package index credentials.
This creates an obligation to maintain an operational security posture that protects your users from malicious updates.
The Roadmap Is Someone's Life
Another kind of trust that the user is placing in you is the trust that you are going to have at least some kind of regard for their usage of your software.
In a perfect world, the user's expectations could be clearly circumscribed. Whatever ongoing maintenance you commit to perform would be encapsulated in clear policies that you'd write up in advance, about exactly what kind of security response policy you have, how you will communicate when you no longer have the resources for maintenance, and so on.
But anyone who has been involved in any project at anything but the most extreme tier of operational maturity knows that 99% of the ecosystem relies on a set of loose conventions around how all that stuff works. We expect that maintainers will generally be around, that they'll use existing tools like an issue tracker for triaging user bugs, GHSA and CVEs for security reporting, that they will mark the project as "archived" and maybe do a final release before abandoning it, that they will maintain a ChangeLog explaining at least a little bit of what is going on.
Users assume that those conventions will be followed when there are any gaps in explicit policy, or indeed if policy is lacking entirely. This assumption is reasonable, because otherwise nobody could ever use any open source without a stack of service contracts that nobody has any time to write.
The strongest such convention is that an actively maintained program will, at least, more or less keep doing what it does as time goes on. A user who has elected to use a bit of open source software has made themselves vulnerable to changes and breakages in that software by the mere fact of using it. In the time that they have used it and invested in it, they have not invested in:
- creating alternative software to meet their needs,
- maintaining data in formats that other software can read, or
- learning how to use existing alternative software.
This can, and does, go badly wrong, when those expectations are mismatched.
How It Goes Wrong
Let's say a maintainer creates an open source paint program, OpenPaint.
An artist, known for their unique style of making blended collages, switches from their previous app, ProprietaryPaint, to this new OpenPaint to make these culturally significant works of art. However, the maintainer decides that the 'blend' tool is kind of a pain to maintain, and they remove it in OpenPaint 2.
A few months later, the artist's operating system vendor issues a security update that breaks OpenPaint, because older versions of OpenPaint were unknowingly abusing some platform API.
The maintainer releases a new OpenPaint 2.0.1 that addresses this incompatibility, but doesn't care about version 1.x any more so they don't bother to update that one.
This places the artist in an impossible situation. They can stay on an old version of their operating system, putting all their personal data at risk. Or they can upgrade to the new operating system, effectively either cutting off access to their livelihood, or forcing them to change their art style entirely.
Now, proprietary software can place users in similarly untenable positions (and in fact, it is more often proprietary software that does). But does the openness completely remove any obligation for this consideration? Should the OpenPaint team have to at least communicate the reasons for doing this, to give the artist some recourse?5
The only thing that "open source" does is that it allows the artist to pay a prohibitive amount of money to a new maintenance team to create a fork. This is rarely the kind of thing that individuals can manage.
This creates an obligation to at least consider how your users might be relying on you.
This is the most complex obligation of the bunch. Obviously it does not entitle every single user to infinite work from the maintainer, but it also shouldn't entitle the user to nothing for having trusted these subtle implied claims that the maintainer is making by making their work public.
It is a nuanced and ongoing negotiation and I do not think we have a clear moral intuition about how it should work out. But we do need to figure out a way to work it out.
It also raises a clarifying question.
Why Are We Even Doing This, and Who Are We Doing It For?
People generally like to do things for more than one reason. We live in an economy where people need to make money, but we mostly prefer to make that money doing things that are useful, and that make other people happy.
So, yes, we create open source for self-interested reasons to improve our reputations, to improve our skills, to increase our influence and to share our maintenance burdens. In so doing we take on some level of obligation to not abuse the trust that is placed in us, even if that level of obligation is not clear.
But if we are not doing it to serve those users at least a little bit, then those motivations are going to quickly ring hollow. We will not increase our reputation with a person if we respond to their every request by telling them that we owe them nothing and that their opinions are worthless. We will not gain influence over a community if we ignore their desires.
Many interactions with open source maintainers are unnecessarily adversarial. This is of course partially the fault of those users, who should calibrate their expectations appropriately.
Still: maintainers could do a better job of listening before these interactions become toxic. There's no reason that "open source users" should be an especially toxic group of people. At this point in history, that group is basically just … people with computers.
It's like that old truism. If you meet one person who is a jerk to you, that's their problem. But if everyone you meet, everywhere you go, is constantly abrasive to you and treats you like you're doing something wrong, maybe it's time to look inward.
If all open source users are entitled assholes, maybe it's time to look for a structural problem.
Surprise, It's About AI Again
Sigh.6
Users hate slop.
I know, dear AI-positive reader, your AI outputs are different from everyone else's, you aren't pushing thoughtless slop into your code, just because everyone else is and it is the inevitable terminus of using those tools. You aren't "lazy vibe coding" with Claude, you're doing "responsible agentic engineering", which is different because you're just built different.
Still, humor me, for a moment. Your users don't know that. They know what it looks like when products that they like adopt slop. They know that they will start leaking data. Developers know that it will make them personally less secure. They know that they can expect more outages and that your code will inexorably decline in quality.
In other words, your users are going to assume that this means you are violating that final obligation that the software should keep working.
Your users are going to tell you to stop, and they are probably going to get mad. Maybe you, or a plurality of your team, also want to stop, maybe you disagree with them, but in any case you need some way to have that conversation in a way that does not immediately overflow into every adjacent discussion forum. Users need to feel welcome in some space so they can have the discussion in that space, and not explode out into a thousand different group chats and social media threads.
This post was inspired by yet another prominent open source community discourse where a ton of angry users showed up to yell at developers to stop accepting LLM-generated code. I'm not going to link to any of these, because we don't need any more fuel for the discourse fire. But there is more than one such case and the pattern is becoming familiar.
On social media - usually BlueSky or Mastodon, but sometimes a user group forum - users become aware of some AI-adjacent policy. They show up in a horde to the developer forum or mailing list. They loudly start demanding the project take a hard stand7 against AI. This pressure is simultaneous, but uncoordinated; extremely repetitive, very diverse, often inconsistent, and pretty stressful, especially if you're a burnt-out maintainer with other things to be doing who may not even like AI yourself in the first place.
Believe me, I get it. It can be very unpleasant to deal with.
Like most problems that AI is causing, though, it's not really an "AI" problem as much as it is a pre-existing dumpster fire that "AI" is pouring gasoline onto. In this case, an online mob is the language of the unheard8.
If Users Are Mad It's Probably Already Too Late (But Maybe You Can Get Ready For Next Time)
One day, all of a sudden, you're getting feedback from a bunch of users that are using inappropriate channels to complain. But did they already have appropriate channels to use?
Did you have a place for people to congregate and discuss your project? To make orderly complaints in a way that will be legible to you? Or do you just have a GitHub Issues page, which non-technical users have no idea how to interact with, and a forum for developers, where users don't know the norms and any arriving brigade of pissed-off users will be seen as disruptive and inappropriate?
I don't want to be throwing any stones from within my particular glass house. Setting up such a place has gotten harder over the years. I don't really have one, either.
Could I have one, though? IRC has been slowly dying, mailing lists are unpopular and present increasingly annoying moderation challenges, forum software is expensive to operate and keep maintained, Discord is a confusing mess and the upshot of all of this is every community needs community management and forum moderation. Which means that for my own small solo projects, I couldn't possibly have such infrastructure because such infrastructure requires a dedicated second person to maintain it, and until someone volunteers for that, it's not really feasible. Even for my larger projects you'd be surprised how slim of a skeleton crew we are getting by with, and we definitely don't have a whole spare maintainer to go manage this, especially as we are under attack from the slopocalypse ourselves.
The nature of open source community is that most communities start too small to need such a thing, grow incrementally until one day they are suddenly way too big and needed one yesterday, and then suddenly they are too small again when interest wanes even a little bit. Even as we need it more and more, building and maintaining community infrastructure remains a challenge.
Even so, having a dedicated place for users - not maintainers - to converse amongst themselves, be an actual community, and present feedback to the developers, is fast becoming a necessary component of a successful community and not a nice-to-have.
In Conclusion
As trying as it can be sometimes, we maintainers all do get something out of open source, and it is good to be honest with your users - and with yourself - exactly what you want to get out of it. In order to know whether the juice is worth the squeeze, we must know both what the juice is, and what the squeeze is.
Part of the metaphorical squeeze is a set of obligations, and those are the most poorly defined of all. We should try to be clear about what those are too. Both about exactly what we believe we are signing up for, and also, about how we are willing to let our users hold us to account for them. Codes of conduct are a start here, but only the absolute barest bare minimum; "do not harass your colleagues or your users" is not a standard of excellence to aspire to, it's just basic manners.
I can't tell you exactly what your obligations are, only try to gesture at my idea of the outlines of the fuzzy moral intuition we've all been implicitly sharing up until now.
Drawing this line is not just for the benefit of the users, either. Maintainers already feel pressure, we already feel obligations. We resent that feeling of obligation. While there are a diverse array of reasons for that resentment, one big one is that it's not clear, even to ourselves where the obligations end. Lashing out by saying "I promised nothing and I owe you nothing!" followed by some choice expletives feels cathartic, but it doesn't really solve the problem, because we clearly don't really believe that's where the line is, or we would have already stopped there. We wouldn't feel the need to say it.
It is going to be a very big collective endeavor to figure out exactly where that line is. The best time to have gotten started on that endeavor was 50 years ago.
But the second best time is today.
Acknowledgments
Thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor!9
-
Somewhat to everyone's surprise, I, too, do things for money, like writing this post. Please remember to like and subscribe ↩
-
Whether it was originally yours, or developed by an employee who happened to be on staff at the time, or adopted by an employee who just started contributing to it a lot, in any of these scenarios a company can benefit from increased consistency and increased familiarity. ↩
-
If the rule is that they must forever endure the searing budgetary pain of gripping the white-hot potato that they unwittingly caught when they first made a good technical choice, this creates a perverse long-term incentive. ↩
-
I also find it darkly amusing that there is an explicit affordance here made for advertising, specifically, "Packages with code that can be used to display ads are fine. Packages that themselves display ads are not." This distinction rather gives the game away, that this is a website for carnies and not for marks, and that at some level we expect our users to deserve a lower level of respect than ourselves. But a full exploration of that is another blog post, or maybe a book, that I don't have time to write right now. ↩
-
If you want the turbocharged ultra-dramatic version of this problem, make it open source drivers for an optical prosthesis that lets the users see instead of an art app. That level of immediate physical dependency could be clarifying. It does also start to edge into an area where you could say that biomedical devices ought to be regulated differently, and that's not really a "software" problem but a "healthcare" problem and I'd mostly agree. Except for the fact that this is a very short distance away from breaking everyone's screen-reader with no notice or recourse. ↩
-
Did you believe I could write a blog post in 2026 which wasn't somehow about AI? I wish I could still believe that. ↩
-
It doesn't help that many of the most pro-AI voices are starting to have an, ahem, discernible political valence that is very unpopular among users. ↩
-
My apologies to MLK. ↩
-
If you read this whole post you can see that I sure need the help with all that. ↩
25 Sep 2026 12:50am GMT




