3964 stories
·
4 followers

Do You Still Read the Code?

1 Share


There is considerable difference between that question and a more innocuous “do you read the code?” The addition of still smuggles with it a theory of progress: reading code is something on its way out, like memorising phone numbers or unfolding paper maps, and the asker seems to want to know if you by chance aren’t one of the obscurantists still clinging to the old ways.

I use AI extensively, and I read what it produces. This is a deliberate choice about how I want to develop software, at least at my job, where I’m expected to be reasonably responsible for the code that I commit and deploy. Other people make a different choice, sometimes with considerable care. But we have begun sharing codebases without necessarily agreeing on what either path asks of our colleagues.

It is very hard to tell which choice will prevail. The still presumes that the matter has been settled, and indeed producing a working application these days has become quite a bit easier. But finding out what it costs to maintain it through changes of requirements, developers, and tooling takes considerably longer. We are making commitments with respect to how teams work now, and their consequences will only later be felt and understood. The confidence with which either mindset announces its victory seems somewhat premature.

Accelerators and vibecoders

As far as I can tell, there are two prevalent approaches to using AI these days.

Accelerators use AI to help translate their understanding into code. They intend to retain enough understanding of the implementation to explain the reasoning behind the translation from intent to code, anticipate the consequences of changes, and maintain the resulting model and its implementation. Reading the generated code is part of that commitment.

For accelerators, language models and harnesses exist in roughly the same category as text editors and their plugins: they can now code faster. They invest in their continued ability to explain and change the implementation. Large changes are slow to review, a generated diff that is determined to incorrectly implement a model is rewritten, cognitive debt1Marginnote storey1Storey, M.-A. From Technical Debt to Cognitive and Intent Debt: Rethinking Software Health in the Age of AI. arXiv 2026; p. 2 piles up whenever the team’s reading falls behind the generating, and the whole thing requires discipline that is very hard to keep.

Vibecoders aim to delegate implementation and its continued revision to AI. Their attention moves towards specifying the desired behaviour, supplying context and domain knowledge, and establishing ways to determine whether the result is satisfactory. Understanding every implementation detail is no longer an intended product of their work.

Vibecoders expect language models to abstract away implementation, putting them in the same category as compilers and frameworks: there should no longer be a need to understand technical details. They invest in their continued ability to specify, regenerate, and evaluate code. Intent debt2Marginnote storey22Storey 2026; p. 3 may accumulate as requirements are rewritten or forgotten, context drifts between sessions, engineering time goes into curating what the agents get to see to keep them away from the “dumb zone,”3Marginnote horthy3Horthy, D. No Vibes Allowed: Solving Hard Problems in Complex Codebases. YouTube 2025; 5:55 and the whole thing stands or falls with the quality of a model that is controlled by Anthropic or OpenAI.

The distinction concerns the developer’s relationship to the output, rather than how much of it the model writes.4Marginnote willison4Willison, S. Not all AI-assisted programming is vibe coding (but vibe coding rocks). 2025 An accelerator might generate almost every line of a feature and still understand what was built, taking ownership of the reasoning behind it. A vibecoder might spend considerable time refining a specification and its acceptance criteria, while deliberately treating the resulting implementation as disposable. Being an accelerator doesn’t require knowing the answer before asking the model—you can use generated code to explore a problem you don’t yet understand, provided that understanding is something you intend to acquire before the code ends up on the master branch.5Marginnote abstain5There is also a third group that rejects AI for programming at all. The objections I’ve come across have mostly been legal (usually copyright-related) or ethical, and while they deserve a serious discussion, it’s something outside of the scope of this analysis. What I haven’t come across is an organisation building commercial software that avoids AI on pragmatic engineering grounds: because they believe the generated code makes their software worse, and in the end costs them more than it saves. If you work in one, feel free to get in touch. I’d very much like to hear about it.

Naur is still undefeated

My own preference comes from what I think programming is for. I wrote before about how programming is essentially pure applied philosophy. I hadn’t read, at that time, Peter Naur’s essay,6Marginnote naur6Naur, P. Programming as Theory Building. Microprocessing and Microprogramming 1985 since brought to renewed prominence by the advent of LLMs, making a similar point thirty-five years earlier.

It is essentially the same argument, made better, by someone much smarter: the code is not the real product of programming. If anything, we mistake the code for an asset, while more often than not it’s indeed a liability. The real product, the asset, is the model, or the theory, behind it. The theory is the kind of knowledge that lets a person not merely do something, but explain it, answer questions about it, use it to project the future, and adapt it if circumstances change. The programmer who possesses it is capable of three things:

“The programmer having the theory of the program can explain how the solution relates to the affairs of the world that it helps to handle. (…) The programmer having the theory of the program can explain why each part of the program is what it is. (…) The programmer having the theory of the program is able to respond constructively to any demand for a modification of the program so as to support the affairs of the world in a new manner.”

In other words, source code is only one kind of product of the activity of programming, but because it’s more visible, it’s treated as more valuable than the understanding acquired while producing it. It’s as if we treated the steam coming out of a coal power plant cooling tower as the main output, rather than the electricity, merely because electricity is invisible.

A part of the job of a software engineer is to name and structure the parts of the business which have until now been understood only implicitly. This has benefits outside of the code: it can help the people whose work we are modelling understand what they do and see aspects of their work in a new light.

Programming is one way to sort the grains of sand of reality.7Marginnote pirsig7Pirsig, R. Zen and the Art of Motorcycle Maintenance. Vintage 2004; p. 72 We distinguish one thing from another, give distinctions names, and build a system whose behaviour lets us discover where our sorting was useful, and where it was mistaken.

Naming things in terms of their immediate appearance locks us into a certain mode of understanding of the product which may be accidental; naming them after their essential attributes is more flexible, but requires much more effort to discover and structure. And running software can only test the consequences of the sorting. Judging whether the model fits the domain still requires contact with the people and processes being modelled. A green test suite only proves that the program does what you said, not that what you said corresponds to reality.

How a programmer understands the domain changes as he works through the implementation. You might discuss a requirement or even whiteboard it, but your conceptual analysis might not survive first contact with the code. When you must account for every case, you might completely change your understanding of the problem and be forced back to square one.

The implementation, then, is not merely a translation of the specification into runnable code, but one of the places where it is revised. Vibecoders seem to bet that the theory can be built by specifying and running software, without dealing with its implementation. I am not so sure about that.

Choice and drift

Choosing the accelerator or vibecoder approach involves different commitments, even though the same person might choose differently for different projects, or even submodules within the same project.

For example, I might lean into vibecoding in throwaway or exploratory projects, where I don’t actually care about the underlying implementation and just want to see something on the screen. The difficulty is that one can cease to maintain an understanding of the implementation without ever consciously thinking about how to correctly delegate it. You start skimming the diff instead of reading it, you need a lot of time to recall or even come up with a justification for a specific implementation choice, and eventually the only practical way to find out what it is that you’ve actually built is to ask the model, with no way to verify if what the model tells you is correct.

This is why I don’t think of the two approaches as some kind of spectrum. You can be an accelerator in one module and a vibecoder in another, but not halfway in either. A drifting accelerator doesn’t end up somewhere between the two approaches; he ends up a vibecoder by default, without the harness around specifications and evaluations that a deliberate vibecoder would have built to make up for the missing theory.

For my own commercial work, reading every line of the generated code is a good way to make sure I don’t drift. It doesn’t guarantee my understanding, but it provides repeated opportunities to find out where the understanding and the implementation diverge.

And they diverge because agents still make dumb choices, and often don’t respect some human dimensions, like time, that aren’t expressible as textual output. An agent that added tests just looks at the terminal output; it doesn’t really matter to that agent that the tests now take three times longer to run. But speed matters to a human. Likewise, agents with polluted context windows drifting into the “dumb zone” will start making obvious local mistakes like declaring React components inside other components, or violating the rules of hooks.

A marriage of inconvenience

I don’t want this to sound like an accelerator manifesto, because I am entirely open to the possibility that the vibecoders are right and AI will make looking at code obsolete—I’m just not seeing enough compelling evidence for that conclusion yet.

What I am certain of, though, is that there is one obviously harmful practice: putting people who prefer different approaches on the same team without establishing expectations and boundaries beforehand, and then keeping to them.

An accelerator may inherit the work of reconstructing understanding that the author never intended to retain or never had in the first place. A vibecoder may be asked to explain incidental implementation choices, even though he spent a considerable amount of time refining his development process to intentionally make those choices disposable. Either can make the other’s work harder by imposing an unstated maintenance expectation.

In ordinary correspondence, sending someone unfiltered AI output is impolite. But when it starts to concern code, intent, and responsibility for issues in production, courtesy becomes an engineering concern. Before merging changes, colleagues need to know how those changes are meant to be maintained: through a developer’s understanding of the implementation, through specification and an established process of code generation and rigorous testing, or through some combination of the two, as long as it’s clear which parts are which.

Whether reading is enough

None of this makes the accelerator’s position comfortable.

Skills deteriorate when they are not used, and it remains to be seen if merely reviewing AI-generated code, rather than typing it out, is enough to take over and switch back to manual coding if the situation should demand it. Some circumstances that were often speculated about, such as the major AI labs going bankrupt or hiking prices, seem to be no longer a concern (we have access to many providers of open-weights models of high enough quality to trundle along if it comes to it), but there might be some dangers to automation that we do not foresee.8Marginnote bainbridge8Bainbridge, L. Ironies of Automation. Automatica 1983 (!!) And perhaps whoever inherits a vibecoded, or even accelerated, codebase might find it prohibitively difficult to maintain.

Declaring that a human remains responsible is easy. Arranging the work so that the human remains capable of exercising that responsibility is considerably more difficult and requires very multidimensional decision-making. It might turn out that the accelerator approach is just a fast track to burnout.

Reviewing everything involves constraints on how much unfamiliar work you can do at once. When coding with AI, you still need to make sure to model your requirements and ensure that the implementation doesn’t drift; otherwise the job of self-reviewing the output is the worst kind of work—“very boring but very responsible, yet there is no opportunity to acquire or maintain the qualities required to handle the responsibilities.”9Marginnote bainbridge29Bainbridge 1983; §1.2

It’s a conscious choice of a demanding practice whose success requires more than good intentions. If software development is ever fully automated, having programmers perform manual coding tasks just to maintain their skill might become a necessary cost for software companies in order to have someone around who can take over in a moment of need.10Marginnote bainbridge310Bainbridge 1983; §2.3

Intent to code

What the AI revolution seems to have revealed about code review is that we never cared about the quality of the code in itself, but about the understanding of the product expressed by the quality of the implementation. Code quality was a useful proxy for that understanding in the time before Claude Code, but a language model can now feign that understanding convincingly. The presence of generated code in the codebase makes it more important to examine the understanding and the implementation separately.

A reviewer needs to distinguish requirements, deliberate implementation decisions, inherited conventions, and choices for which no rationale was recorded. Those distinctions should remain connected to the code as it changes.

The point is not whether a specific piece of code was generated or typed on a keyboard. Humans make incidental choices that are hard to explain, too, but it’s considerably more difficult to make a great many of them and still end up with working software. Agents do that all the time, but the fact that they do so is not a reason to dismiss them outright: it’s still entirely possible for them to implement explicit decisions faithfully.

Consider the following story: the business requirement is that a user may request password reset links and that they expire. A developer chooses a particular expiry period. An agent chooses how to represent and check it. The resulting code implements those decisions in several places, but the intent is lost—when a reader comes later and sees a value of expiryTime = 6h, he can see what the software does, but the six hours could have come from several places: an explicit business requirement, an existing convention, a considered trade-off, or a guess that no one challenged. To decide whether the value should change, the reader needs to know what justified it and whether those circumstances still hold. The decision’s result is in the code, but on its own it doesn’t preserve enough of its history to reconsider it fully. This is intent debt, and reading every line of the code doesn’t pay it off.

One promising way agents can help here is by leveraging their ability to summarise, letting a reviewer trace those relationships and see where a choice lacks an explanation. If you review the code yourself, you can use a tool like Crit to make sure the implementation didn’t stray from what you intended. Or you can use CodeRabbit’s Change Stack, or my own intent-stack skill, to gather context and generate an aid for the reviewer.

As for automation, greater delegation makes durable goals, constraints, validation criteria, and relevant context increasingly difficult to preserve as the generated codebase grows. Simultaneously, that preservation becomes increasingly important with the growth of the number of lines of code, because the agents doing the implementation might make contradictory decisions simply because they didn’t chance upon the relevant piece of context, or they ascribed authority to information that was meant to be disposable. Those records must remain usable when sessions end, agents change, and the implementation is regenerated.

The various experiments in building “software factories” and “graph engineering” seem to me to be attempts at making that delegation deliberate by cataloguing intent in ever more fractal structures of summary, so that trees or graphs or swarms of agents can communicate at different levels of generality without polluting each other’s context windows with things that aren’t relevant to them. I’m not very in tune with this approach, but a reasonable starting point might be reviewing StrongDM’s account of their software factory, which runs on two rules: no writing code by humans, and no reviewing code by humans. Instead, they validate agents’ work against scenarios kept outside the codebase.11Marginnote wsff11For an opposing view, see Horthy, D. Why Software Factories Fail

Two paths

There are, then, at least two kinds of progress in AI-assisted programming: one helps developers understand and interact with the implementation, and one aims to remove the need for that interaction altogether. While the latter seems to be getting more of the limelight, these are different paths, they require different tools and different approaches. Both may improve, but it does not follow that the goal of the accelerator is to become a vibecoder. Ceasing to read code is not, in itself, progress.

But before asking whether your colleague still reads code, perhaps consider whether you’re still expecting him to maintain yours.

Read the whole story
emrox
12 minutes ago
reply
Hamburg, Germany
Share this story
Delete

EuroBirdPortal - bird migration visualization

1 Share

Link

Social

Embed this visualization

(Select left or right map)

L R

Read the whole story
emrox
20 hours ago
reply
Hamburg, Germany
Share this story
Delete

React 19.3

1 Share
React 19.3 adds new features like View Transitions, Fragment Refs, browser(), Trusted Types, and more.
Read the whole story
emrox
1 day ago
reply
Hamburg, Germany
Share this story
Delete

On-device models

1 Share

Today we're launching Desert Ant Labs, a European frontier AI lab building opinionated on-device intelligence. We believe the best path to efficient intelligence starts on-device.

We're building small, specialized models for audio, vision, and text – each model answers in milliseconds, and costs nothing to run, so you can put intelligence in every product interaction, without being limited by token cost or inference speed. Small enough to run on a five-year-old phone, fast enough to use on every frame or keystroke, and better than the API call you're already paying for.

The first 18 models are live today (12 stable and six in beta), accessible via one SDK for Swift, Kotlin, and JavaScript. One model per task, each built to be the fastest way to complete that task on a device:

  • Voz: transcribe 10 minutes of audio in two seconds on an iPhone – 4.7x faster than Whisper – with a start and end time on every word.
  • Clear: a 9MB model that can turn a five-minute laptop recording into studio quality audio in one second.
  • Redact: mask names, addresses, and card numbers, in real time, in 27 languages, so they never reach your servers.
  • Tongue: identify 84 languages from three words, with a 2MB model.
Language ID accuracy, three words in

Tongue · 2MB 0.933

293MB detector 0.887

Tongue names the language from three words, scoring 0.933 at 2MB against 0.887 for a 293MB detector.

And that's just to name a few. You can find full specs and benchmarks for the other fourteen, on desertant.com/models and Hugging Face. Every model is free up to 100k monthly active devices. No tokens, no logins.

Personal data caught, by system

Redact · 12MB 88.8

GLiNER-PII · 2.3GB 91.1

Rampart · 14.7MB 61.4

OpenAI filter · 3GB 60.2

Redact catches 88.8% of the personal data in a text, close to the 2.3GB GLiNER-PII, from a 12MB model.

We're building this in Europe, where "on-device" is the sovereign default. The data never leaves your customer's hands, the feature never depends on someone else's cloud, and what's never been uploaded can never be compelled.

How we got here

For five years we've been building our video app, Detail, with an on-device first approach. But when we introduced features like Auto Edit to create short clips, or audio enhancement for podcasts, we had to fall back to cloud APIs. And as the popularity of Detail grew, so did our infrastructure bills.

Every few months I'd hunt for useful on-device models. I'd surf Hugging Face for a model that could find filler words or clean up a recording. And, every June, we'd get great new tools to build with but the industry wasn't moving fast enough. The foundation was there: the chips, Core ML, the research. What was missing was everything between that foundation and actually implementing a feature in your app: a model you could drop in and ship with a few lines of code.

So, we trained the models ourselves. It turns out training a model is a product design challenge, and product is what we know. We designed models and local inference that beat cloud services on speed, quality, and cost, and outperform other local and cloud models on the task itself, at a fraction of their size.

We replaced Dolby for better, faster audio enhancement with Clear, and made our on-device transcriptions 5x faster with Voz. We also replaced Claude Sonnet with Clips, our 284MB model that turns a 10-minute video into a dozen clips in 5 seconds – 10x faster and using 470x less energy than Sonnet, with the same quality.

Clear audio enhancement speed, 5 minutes of audio

iPhone 16 Pro 302x

MacBook Pro (M5) 345x

Clear enhances, masters, and re-encodes a clip on the device, best of three, from a 9MB model. 302x realtime on a phone. Transcription speed, 30 minutes of audio

Voz 319x

Apple SpeechAnalyzer 78x

Whisper large-v3-turbo 50x

Realtime factor over 30 continuous minutes on an M3 Ultra. Voz reaches 298x on an iPhone 17 Pro.

Detail 6, which will launch with iOS 27, replaces all of our cloud APIs with our own models, running entirely on the device.

We've all spent the past few years building with LLMs as if they were just another API. And, amid the hype around generalist frontier brains, we almost forgot they're not the only option.

Every developer I talk to has a wishlist of on-device models they'd build if cost wasn't a factor, or a feature they're bleeding tokens on that they'd happily swap for a local model. A call that runs the same way a hundred thousand times a day: cleaning a recording, tagging a photo, pulling a date out of a sentence, catching a name before the text hits your servers. None of these needs a frontier model.

NVIDIA's own researchers pulled apart three agent systems and estimated that 40 to 70% of their calls to a large model could go to a small, specialized one instead.

The compute is already paid for

The industry will spend about $450 billion on data centers this year. Meanwhile, the world ships more than a billion phones, tablets, and laptops with increasingly capable chips, perfectly suited to these kinds of tasks. There's more compute available in people's hands than in every AI data center on earth.

We have an unfair advantage with free inference. No per-call cost, so a feature runs on every message instead of the ones you can afford to check. No round-trip, and your customer's data never leaves the device. When inference costs nothing, the way we build products changes entirely.

Little brains in every product

To build with local models, the developer experience has to get a lot better. You need models you can use commercially, that beat the alternatives on your task in speed and quality, that you can drop into your app with a few lines of code, and are easy to discover.

Think of the first hundred models as the cerebellum, the little brain. The little brain handles the always-on work – balance, timing, the skills you never think about, so the rest of the brain is free to think. That's what we're building first: fast, specialized models for the work that runs all day, on the device, for free.

Then comes the cortex, the layer that decides which model answers. A small local model first, a bigger one when the job requires it, and the cloud only when the work has to leave the device. As open research advances and device silicon becomes more capable, the local models grow, and we'll train larger ones ourselves. Frontier intelligence, built from the small end up.

Cloud labs ship neutral models because per-token pricing needs a neutral model. Every Desert Ant model ships with a default we choose, and the levers you need to change that default. We optimize the model and the runtime together: on an iPhone, Clear and Voz run on the Neural Engine, and in the browser, Clear's same weights run through WebAssembly.

The SDK

Ready to get started? You can implement Desert Ant models in your app with our native Swift, Kotlin, and JavaScript SDK, available on GitHub.

Our docs are written for developers and agents and you can try the models on your Mac with the CLI, or in your browser on Hugging Face.

Building something cool with our models, or want to build them with us? Get in touch.

Read the whole story
emrox
5 days ago
reply
Hamburg, Germany
Share this story
Delete

Building a Wall Lamp From Scratch

1 Share

Somehow, I spent 8 months of my free time designing and building a wall lamp from scratch. I didn’t have prior experience in woodworking or LED strips. Read on for how it came to be (and how it turned out).

Ambitions

The lamp topic actually started with the living room.

Having moved recently, I still had a gap to fill on the wall. Indirect lighting is the best kind of lighting (this needs no debate), so why not build a wall lamp that illuminates the whole living room? And while switched off, it’s an art piece? Consisting of lasercut Plexiglas panels that are backlit by LED strips, with support for animations? With wood paneling on the sides to make it look more classy?

Daydreaming of what this elusive piece of furniture could look like, I drew some mock-ups. I then came to my senses and realized:

  1. I had never worked with LED strips before,
  2. I had no clue how to mount the Plexiglas panels,
  3. I had no idea how to design the lamp so it could be mounted on the wall, and
  4. I had zero experience in woodworking.

I estimated that starting and finishing this project would take me 2 years, with a 99% chance of it never being finished. So I just hung paintings instead:

After congratulating myself for being such a mature decision-maker, I stepped into the rabbit hole of DIY lamps anyway, by building a simpler wall lamp for the bedroom. The idea would be to build a lamp as an art study, collecting enough experience to have a realistic chance of building that elusive lamp in the future.

So back to daydreaming, the best phase of any DIY project.

Mock-Ups

In the bedroom, the bed frame is made of beech wood. A wall lamp with beech wood panels that have LED strips hidden behind them would complement this well.

Roughly like this, but twice as long and not for 600€:

Or like this:

but with individually controllable LEDs so that different sections can light up, and it can either illuminate the room or just be a reading light. Ahh, daydreaming.

The next day, I committed myself and bought a second-hand beechwood countertop from the local classifieds, for 15€. It had legs attached that I didn’t need, but those turned out to be discontinued IKEA legs that sold for 30€ on ebay. 💰💰💰

That was back in May 2025.

Back to the mock-ups, specifically, designs that would fit the aesthetic of the bed:

I went with design #1. The black rectangles would be backlit Plexiglas panels.

My aspirations were clean-looking wooden panels from all angles, without visible bolts or cutouts. I did not know yet how the panels would be physically connected to each other. A milling and drilling solution where the panels are connected with threaded rods was thinkable, but had me worried about structural integrity and my wooden panels not being thick enough.

Instead, I planned to build a frame out of standardized aluminium extrusion parts to which the wooden panels could be attached. (I also had never worked with such aluminium parts before.) Here’s a mock-up from mid-June 2025:

The LED strip would wrap all around the aluminium extrusion, hidden behind the wooden panels. The power supply and control electronics would hopefully fit behind the panels. The mounting mechanism was not thought through at this point.

Around this time, I made the mistake (?) of chatting with my work colleagues about my lighting ambitions. Anyway, on to building this thing.

Build Log

August 2025 – Planning

A lot of time was spent on planning what components to use.

  • The LED strips would be SK6812 ones. 5V strips have the downside that long segments need power injection in multiple locations to end up with consistent brightness, but the compact lamp layout would make this easy.
  • For the LED controller I’d use a QuinLED Dig-Uno, which I decided for after watching a comparison video by @MakeItWorkTech (highly recommend!).
  • WLED as the software was an easy pick.
  • The WLED power calculator told me a 75W power supply would suffice. A Meanwell PSU would do the job. Colleagues advised me against picking those for their coil whine (jumping ahead: it’s a non-issue).
  • $LLM told me I would need LED diffusors, otherwise LED hotspots would be visible. I obliged and picked tall ones after watching this massively useful comparison video.
  • For the aluminium extrusions, I would be using 3030 and 3060 sizes (30x30mm, 30x60mm) based on gut feeling, and because the Meanwell PSU and Dig-Uno are 30mm tall.

Early September 2025 – Sizing and Parts Ordering

Onto sizing. The PSU is the largest component hidden behind the wooden paneling and dictates the height of the panels and the aluminium extrusions. The overall width would be 180cm. With 60 LEDs/m, I would end up with roughly 220 individual LEDs.

To avoid bad surprises after cutting/drilling anything, I maintained a CAD model throughout the project in OpenSCAD:

Barebones CAD model, early September

I ordered all the parts, unleashing a fork bomb of non-reroutable shipments for my neighbors to accept while I wasn’t home.

Late September 2025 – Aluminium Test Fit

A test fit with the aluminium extrusions revealed that connectors in the inner corners would be too weak for the load I expected.

I ordered 2x2 connector plates that would connect the aluminium parts on the outside.

Mid-October 2025 – Shifting Gears

A certain colleague at work remembered me musing about indirect lighting in May and asked about the project status over lunch. At this point, little tangible progress had been made.

I have great colleagues, so that conversation ended with bets being placed by multiple people on when this lamp project would (ever) be done. The bets ranged from December 1st 2025 (impossibly early) to April 15th 2026 (an insult dressed up as a bet).

I picked up the pace.

Late October 2025 – Woodworking

I couldn’t put off the irreversible step of cutting the countertop much longer. I got it done, that is, someone else cut it for me at the local makerspace:

November 2025 – Wall Mounting Decisions

In June’s mock-up, the lamp was mounted with three hypothetical wall hooks:

These hooks would either have to reach over the circumferential LED strip or interrupt it, producing shadows or ugly dark spots. Basically, they would maximally spoil the aesthetics. Can’t have that.

After thinking long and hard, I decided for the mounting solution with the best visuals and best structural stability: two wall hooks that mount into custom mounting plates attached to the aluminium extrusions, hidden behind the boxed-in section of the lamp:

This solution would also be the best in creating additional engineering effort, cost, project delays, and general headache. Let me elaborate:

  • The wooden panels are heavier than the extrusions. Looking at the lamp from the side, the center of gravity would therefore be several centimeters away from the wall. The optimal mounting point that minimizes mechanical stress on the extrusions is close to the center of gravity, e.g. in between wood and extrusions:

    Accommodating space for the tip of the wall hook and the mounting plate requires routing a pocket into the wooden panels, either with a handheld or CNC router (neither of which I had used before).

  • Each mounting plate needs to support 6-7kg. I would not trust a plastic 3D printed part to sustain this load over time.

  • Looking at the lamp from the front, the center of gravity is not centered between the wall hooks, because I thought in June that an asymmetric lamp would look cool (and had already cut the countertop that way):

    Naïvely hanging the lamp on the two wall hooks would result in the right side tipping down, with the left wall hook not contributing anything. A balancing solution would be needed, either by adding ballast to the left side, or by removing material on the right side.

The obvious solutions to these challenges are to look for thinner wooden panels to reduce weight, or to fix the asymmetry by shortening the right panel, but those are weak solutions. I’d rather engineer myself out of the corner I’ve engineered myself into.

Hence, I designed the mounting plates and ordered galvanized steel versions from PCBWay. With that, I crossed off my bucket list item of ordering custom steel parts for a hobby project. 🙂

Routing the pockets to fit those parts in — well, back to youtube for watching tutorials. To fix the asymmetry, I would be using ballast steel pellets I still had lying around from another project.

Mid-November 2025 – Plexiglas Panels

LED-backlit Plexiglas is all the rage for WLED projects on the internet. There exists a material that appears black when lit from the front, and color translucent when lit from behind. I had to experience this wondrous material myself.

The exact product name is Plexiglas Black & White 9H04 SC. To save myself from more makerspace visits for lasercutting, I had my parts cut and shipped from Acrylglas Shop in Germany.

Quick demonstration with the protective film still on:

Mid-December 2025 – Routing & Drilling

It was time to get serious with marrying aluminium and wooden panels. The two wooden panels would be affixed to the aluminium parts with L-shaped aluminium brackets.

First step: marking out the drill holes for the L-brackets and the pockets for the steel wall mounting plates:

3D printed alignment jigs for drill holes and pockets

The pre-tapped M8 threads in the extrusions came in handy (see the left photo). I had paid extra for them when buying the aluminium parts three months prior, without a concrete use case in mind. Lucky me!

I took my parts and templates to the makerspace and routed the four pockets with a handheld router equipped with a guide bushing.

The first pocket (top left in the second photo) came out disastrous, but it’s not going to be visible from the front anyway. Lessons were learned. Also, I learned that the clean and fast way of affixing templates is via two strips of adhesive tape (one on the wood, one on the template) and superglue in between.

Also, drilling holes for the L-brackets, and inserting threaded inserts with yet another jig. I chose threaded inserts and bolts over wood screws because of the far greater number of mating cycles they offer. Modularity is key!

It was now possible to attach the wooden panels to the extrusions for the first time:

Everything lined up. :)

Mid-to-late December 2025 – Shiny Metal Parts

Christmas came early by one week: the PCBWay parts arrived.

Now I know how all the popular DIY youtubers feel when they inspect their shiny new CNC-machined parts. I also know why they need those sponsor segments now, based on how much lighter my wallet feels (we’ll get to this in the end).

Timing-wise, I had ordered the steel parts, then templated and fully routed the pockets before the steel parts even arrived. This was a bit of a gamble, but avoided weeks of idle project time. I was 99% certain the parts would fit based on the CAD model, but seeing it in person was still a relief:

Early January 2026 – Main Assembly

A million little steps for putting it all together: polishing the wooden panels, cutting the LED channels, soldering the LED strips, gluing them down, dremeling cable channels (I bought a Dremel), cutting and dremeling the LED diffusors to size.

I had tried soldering the strips with my Ersa Tip iron at home, and the solder never stuck. A week later, I took the whole aluminium frame to the makerspace to use their soldering station and it was a breeze. Phew.

Finally, all the electrical and electronic components could be mounted in their intended final location:

With everything affixed, it could be put on the wall. Well, kind of:

Looking good, but there’s a big issue: an unplanned 1-2mm gap between the panels where light is bleeding through.

I had stashed the wooden parts in the bedroom all along, but after marking out the holes for drilling, I left them in the living room next to the radiator. The humidity and temperature difference must’ve shrunk them. I ordered adhesive felt strips to fill that gap.

Mid-January 2026 – Weight Balancing

The missing step before the lamp could be hung on the wall was solving the weight imbalance issue.

The plan was to attach 3D printed end caps to the tips of the aluminium extrusion. Those would fulfill three purposes:

  1. Capping off the open ends of the LED diffusors.
  2. Providing a hollow compartment to fill with steel pellets, on the lighter, left side.
  3. Providing space for branding (more details later).

In terms of CAD work, those were the most complicated parts to design in this project. Twice I thought I had printed the final parts, only to realize that I had forgotten about a specific design constraint, or that some dimensions were off.

Mid-January 2026 – Burn-In Test

Heat dissipation had me worried for a long time. The PSU and QuinLED are elegantly hidden, but are also boxed in from all sides with no room to breathe once the lamp is on the wall.

My main mitigation was to attach the PSU to the aluminium extrusion with an all-metal connection, which would hopefully suffice as a heatsink. The QuinLED sits on a printed part made of PETG, and would just have to hold on.

To check how much I would be in trouble, I ran a burn-in test. I placed Zigbee temperature sensors all over the lamp, positioned it flush against the wall, and ran it at full brightness:

After 90 minutes, the temperatures had reached an equilibrium below 40°C that was far away from the ~65°C I had considered worrying.

Burn-in test results

Great! Almost done. Time to attach the Plexiglas panels, put it on the wall, and balance it out. And then…

Finished Product

On January 22nd, after 8 months, the lamp was complete. The money shots:

"Put on the performative cushions, the internet is coming over!"

I’m very happy with the end result. It looks just like the mock-up, what can I say.

The exposed power cable and some ugly spots on the wall couldn’t be avoided (these are brick walls, and I’m renting this place). The brightness is enough to tell blue and black socks apart, but I wouldn’t use it for vacuuming. I measured the power draw with an IKEA plug, and saw a maximum of 40W. Fun fact: the closest completion date a colleague had predicted in October was January 24th, off by only two days. 🎯

And because each LED can be controlled individually, here are all the features off-the-shelf lamps can’t do:

Reading lightsFull brightness vs. go-to-bed modeDid-you-know-that-every-single-LED-is-controllable mode

And obviously, being powered by WLED, it can be integrated into Home Assistant.

Two more design details worth mentioning:

Cost Breakdown

That brings us to the expenses for building this lamp:

CategorySum [€]Sum, in use [€]
3D printing (power & materials)12.896.02
Bolts & screws49.2430.83
Consumables (solder, tape, etc.)23.891.83
Lighting134.93114.90
Aluminium frame26.9425.06
Frame connectors, made-to-order107.0268.93
Frame connectors, off-the-shelf57.0520.99
Vanity items (acrylic, badges)102.05102.05
Wooden countertop15.0015.00
Customs52.6952.69
Shipping74.4374.43
Makerspace donations23.0023.00
Tools (bought)111.37111.37
Tools (rented)21.1221.12
Income-25.90-25.90
Total785.72 €642.32 €

“In use” refers to parts on the wall or unavoidable costs in obtaining them (e.g. buying a 5-pack of fuses but using only one).

Regarding the made-to-order parts from PCBWay:

  • One mounting plate was 19.05€.
  • One furniture badge was 29.77€ (ouch).
  • The 2mm thick PSU mounting plate was 30.84€.

Plus bank fees, plus shipping, plus customs. Compare that to the acrylic panels which were produced, lasercut, deburred & polished in Germany for 42.52€ plus shipping – an outright steal.

Looking back, I considered 600€ for a backlit piece of wood to be disproportionately expensive. Well well. And my calculations do not even include the time I spent on this project.

Final Thoughts

Do I like the finished lamp? Yes. Would I do it again? …maybe? But I’d approach it differently.

CAD model evolution

High standards, doing everything for the first time, and mild deadline pressure made for a stressful combination. Additionally, the last third of the project was rather dreadful, because all of the fun design and planning steps were complete and only menial work was left. This might be unavoidable for such a project. Let’s also not talk about the eternity it took to write this blogpost. 🫠

If I may give one piece of advice after all of this, then it’s to try and find people who encourage you to finish your projects. Conversely, I will try and poke others a little more.

With the bedroom lamp done, am I going to tackle the living room lamp next? Not anytime soon. But I may have ordered Plexiglas test parts to kickstart the daydreaming and prototyping…

Read the whole story
emrox
5 days ago
reply
Hamburg, Germany
Share this story
Delete

AI;DR (AI; Didn’t Read)

1 Share

I’m SUPER jealous that I didn’t think of this first...

Alas! Hat tip to seclilc for tweeting this gem out two days ago.

lil c@seclilc

AI;DR (AI; didn’t read)

6:13 PM · Aug 15, 2026 · 346K Views

83 Replies · 2,09K Reposts · 16,6K Likes

I’ve been thinking about it ever since. Why? Because there is growing grumbling among everyone about AI writing. And it’s not just others; it’s me! I am getting to the point where I physically flinch (sometimes dropping my shoulders and hunching, or having a slight eye twitch) when someone I respect sends me unfiltered and unedited AI output.

Look, I get it. It’s Q3 2026, and we should expect that everyone is utilizing AI at SOME point in their process (sourcing ideas, creating outlines, refining prose, etc.).

However, I have a new policy.

If you’re not bothered enough to review and edit it...

...then I’m not going to bother reading it.

Yes, there are certain situations in which we should expect 100% AI-generated copy. Customer support would be a perfect example. We’re not looking for artisanal “did you make sure to reset your phone” style dialogue.

But if you’re my colleague and we’re in a Slack discussion and you post a wall of Claude output, then I’m afraid I received a different message than you intended.

The same is true for people’s newsletters and social content. It’s your name on it; are you proud of the prose and weird AI-isms sprinkled throughout it? If so, great. But I can ask Claude directly if I wanted to.

TL;DR (too long; didn’t read) was the solution for social media.

AI;DR (AI; didn’t read) is the solution for AI slop.

May you embrace this policy yourself and seek out those willing to care enough to prioritize a human touch when they talk to you.

Update 1 2026-08-17: Daniel in the comments shared a wonderful website dontpastetheai.com. Amazing. I especially loved the Take me to the Angry Version version. The intro header says it all.

Update 2 2026-08-18: This made it to #1 on Hacker News on 2026-08-18 with >600 comments. It apparently struck a cord.

Update 3 2026-08-27: Given the popularity of AI;DR, I created graphics that you can use to spread the word!

Read the whole story
emrox
5 days ago
reply
Hamburg, Germany
Share this story
Delete
Next Page of Stories