Claude (Necromancer)
We all have them: the projects we’ve started, maybe we finished, maybe we even shipped, but for one reason or another, they fall into disrepair. Maybe there was a breaking change with a dependency you couldn’t justify spending the time to fix. Maybe it was costing you too much money to offer it. Maybe you just got bored of it.
Sometimes you find a use for an old project, but it’s been so long that the thought of getting back into that codebase is a non-starter. You can’t bring yourself to even get started.
It’s a different world now, though. We have necromancers. We can bring stuff back from the dead.
Visiting the Graveyard
I started NoraSector in 2020. At first it started with me just wanting to control a Uniden trunking scanner with my phone and stream its audio live. Then it evolved into learning about SDRs to build a simple software-based one. Then it was late nights of reading and watching videos about DSP to build my own SDR trunked scanner backend, learning WebRTC, learning Svelte, and combining them together into what in my opinion was the best radio scanner website out there.
Most radio scanner apps either had a 2005 Broadcastify single-channel stream, often with an incredible latency delay compared to a real scanner, or just recorded channels and let you listen to the recordings. Neither were sufficient for what I wanted. I wanted real-time audio for every channel (or as close as I could get), I wanted instant recordings, and I wanted a nice user experience.
NoraSector was innovative in how it used WebRTC and a custom tuner backend that enabled ultra-low-latency streaming and controlled how channels were muxed. Trunked radio systems have hundreds or thousands of channels, and you’re usually only interested in a handful. Each tuner managed the WebRTC connection to the client and their channel subscriptions, emulating the experience of having a real handheld radio scanner that could pick up anything.
The UI was adequate in the “backend engineer tried to make a UI” sort of way. I made it work. The real magic was all in the backend. I effectively turned a single SDR into a $300 trunked radio scanner accessible to anyone on the Internet. As a product, it was really quite good.
Why It Died
King County changed radio systems from the old Motorola SmartNet protocol to a newer P25 digital system in 2023. My SDR software, Turbine, was built for Smartnet, and it took me months to reverse engineer other projects and build a Smartnet scanner in a way that worked for me in Go. Go wasn’t really the best choice of languages due to being garbage-collected, but the goroutine model worked well and it was what I knew, and it was a tremendous challenge to build my own DSP block system to read IQ samples from the radio and turn those into useful pieces of data and audio.
When the P25 system went live, I had to shut it down. I didn’t have the energy to try to add P25 support myself. I was sad about it – I built it for myself, and there was no real alternative to it – but life moves on.
Resurrection
Anthropic’s $50 credit promotion they ran after launching 4.6 worked on me. I burned through it in a couple days, and realized that it was not far-fetched to use Claude to attempt the form of necromancy I had in mind. I upgraded to Claude Max and dug in.
The minimal thing I had to do to bring back NoraSector was to update the SDR code to support P25. If I did that, there’s no reason the rest of it couldn’t work.
I cloned my old Turbine repo and pointed Claude at it. I spent a couple evenings trying to get it to add a P25 backend in addition to the existing SmartNet one. It actually didn’t work, though: it understood Turbine’s structure, it implemented a lot of the DSP blocks from GNURadio, and it would compile and build and kinda/sorta work to decode the data channel, sometimes. But this is probably the most complex software I’ve ever written, with lots and lots of math I don’t understand. So it’s definitely not “perfect” yet.
I didn’t let that deter me, though. I don’t have the same sense of pride as a younger version of myself. I’m not above just using someone else’s code. So instead, I forked trunk-recorder, and had Claude write me streaming and recording plugins for it that were compatible with my existing NoraSector backend. It was able to stream audio like I was in Turbine, but using much more optimized C++/GNURadio code that is far more efficient than my Go code (latency is actually slightly higher compared to Turbine due to how GNURadio works, but we’re talking like 50ms max).
Let’s be clear, though: I’m not a C++ guy. I don’t know the exact specifics of how you should do things in C++. But I do know what I want done. And I was able to tell Claude exactly what I wanted done, to have it extract the interfaces from the rest of the NoraSector code and use those to build the plugins that stream audio and upload recordings to the system in the exact same way as I had with Turbine.
I couldn’t just stop there, though. There were so many things I had wanted to do and just lived with. I didn’t have to live with them anymore, though.
I had Claude take the existing UI code and rewrite it in the latest version of Svelte. It fixed a bunch of little bugs and made it good looking, too. It went from amateur hour to professionally polished, and it did that in less time than it’d take me to update a single component.
I am not a web developer by trade. I haven’t written front-end code for money in at least 5 years, and that was just adding some internal tool UIs. Now I can make interfaces that rival some of the best front-end devs I ever worked with.
Recordings


Tuned channels


You’ll notice in the recordings screen there’s transcriptions now. That’s a new feature that, again, I wouldn’t have done without Claude. I added it in a couple hours.
Claude updated the trunk-recorder plugin to write to a queue on the SDR machine, it wrote a Python script to wrap the queue and process transcriptions and upload them using the Whisper model, it updated the backend code to accept transcriptions (which come in separately from recordings, so recordings come in instantly and transcriptions can be a little delayed), it updated the tuner to propagate them to the UI, and it updated the UI to display them.
This would have taken me God knows how long during my normal after-the-kids-go-to-bed-until-I-fall-asleep project cadence. I just wouldn’t have done it. But I did it in a single evening.
The last step was to get it back out on the Internet. The architecture and infra are a little complicated: the SDR machine in my house sends protobuf-wrapped Opus frames over a Wireguard tunnel to an ingester, which pushes them into Redis pubsub, which is read by the tuner, which needs to expose itself so WebRTC can make a connection.
Claude helped me land on fly.io as the right balance between cost and features. I’d never used fly.io before, but it didn’t matter. Claude figured it out. It translated all my old deployment stuff for Kubernetes into some simple scripts I could use to deploy on fly.io. I was up and running in about an hour. It even helped me write a skill for itself that lets me deploy with a slash command.
Adapting to the New Normal
As a disclaimer: I’ve been in the industry for almost two decades. I started writing code in my bedroom when I was 12. I have a lot of knowledge and experience, the type you could only get being around when the Internet was nascent and if you wanted to do something, you had to find ways to do them yourself. You could say I know a bit about computers. I know what I want, and I generally know – at least at the conceptual level – how to do it.
This was all using existing codebases that were known to work. trunk-recorder uses GNURadio which is very well documented online. The NoraSector codebase isn’t terribly complicated. It’s basically just routing audio around, and the UI connects to WebRTC. And it already existed. Claude had a working frame of reference.
Turbine was well-structured for what it was, and was designed to be easy to add other systems like P25 into, but even hours with Opus, telling it exactly which code to translate/copy couldn’t make it work. It’s not there yet for everything, although I wouldn’t be surprised if it was one-shottable in a couple years.
That being said, it has been a fascinating experience.
You think about your project far more deeply at a product level because you’re not hung up on little implementation details. You can think more about the system design, about the user experience, about the marketing and the polish. You still need to find a way to test things to make sure they work, though, and work to your satisfaction, not Claude’s satisfaction. Only you know what you want.
You are a manager running a team now. People have their strengths and weaknesses. You are constantly adapting to what Claude’s strengths and weaknesses are, and finding ways to get it to do what you want done. Stay curious. You want to make sure the plan you come up with for Claude to implement is clear to Claude and clear to you. Ask it questions to make sure it’s thinking the same thing you are, or maybe it has an even better way of doing something (this happens a lot).
Your time is your most precious asset. Prompting for five minutes to get the equivalent of an hour of writing code yourself is a no-brainer. Most code isn’t special or novel. Younger me took great pride in the code I wrote, but the code is a commodity now. Claude spits it out in seconds. Code has always been a means to an end, and the craft just doesn’t matter as much anymore. We can commiserate over this and lament the end of a large aspect of our trade, but it’s true.
The Future
No manager has ever really cared about the actual lines of code you wrote. They cared about what the code you provided was able to do in terms of actually solving problems and providing value. And that’s what you’re still able to do, but faster and across domains you never bothered with before.