Why write yet another astrophotography processing suite? I ask myself that about AfterNight very often.
Today the field is crowded. Besides PixInsight, there is Siril, very mature now, with a Python scripting framework that lets the community build almost anything on top of it. There is Seti Astro Suite Pro, by Franklin Marek, which follows a different vision from Siril’s and has earned its own place. There are well-known tools for specific jobs, like the long-standing DeepSkyStacker, StarNet++ and GraXpert, and several paid tools that changed astrophotography processing for good. And AI now lets people with no programming background build tools for very specific purposes.
How it started
It wasn’t always like this. Four years ago Siril was far less capable than it is today, and apart from it and DeepSkyStacker there was little open source to choose from. I’ve always loved astronomy, but I only took my first steps into astrophotography in 2019, and back then I couldn’t afford PixInsight or any other commercial software.
One night I was having some beers with a friend who was also into astronomy (some nights we drove 150 km out of Buenos Aires to take pictures), and I said, “I should write my own application to process our pictures.” We laughed and moved on to other things. But on the walk home I kept thinking about what I’d said, and as soon as I got home I went to my studio and started coding.
I knew very little about image processing, so I had to learn it all from scratch: books, articles, papers, other open-source projects, and a lot of failed attempts before anything worked. Eventually I could compare AfterNight with the popular tools, not as competition but as a reference.
Why not contribute to Siril?
That was the first question I asked myself: why not take an existing project, like Siril, and help make it better? I think Siril is the best open-source option for astrophotography: its feature set is incredible, and it is mature and really robust.
But I wanted something closer to PixInsight. Not a clone: something that handles complex workspaces the way PixInsight does, written in modern C++, with a modern UI, natural integration with third-party tools such as GraXpert and the RC Astro tools, and yes, some of PixInsight’s most powerful ideas. Any open image can be the live mask of another, PixelMath can name any open image in an expression, and a few of its best processes have an equivalent. I took design ideas from it and wrote my own implementation.
So what does “from scratch” mean here? The application is mine: the architecture, the engine, the workspace and the UI. I didn’t reinvent every wheel, though. Where a published implementation was the right starting point I started from it, credited in the file: the demosaicing kernels from RawTherapee, the NL-Bayes and DA3D denoisers from their IPOL implementations, Siril’s automatic gradient removal and its drizzle pixmap, DeepSkyStacker’s adaptive weighted mean, and a PixInsight script for narrowband color mapping. Those files are about 2% of the product code: 26 files, about 17,000 lines of 784,000.
The choices
I chose C++ because I wanted AfterNight to be fast and memory-efficient, because the libraries I wanted to stand on, Qt, OpenCV, cfitsio, LibRaw, FFTW and G’MIC, are C and C++, and because it is the language I know best.
I chose Qt because I wanted it to look great, feel modern and stay portable.
I chose the GPL (version 3) so I could build on the excellent GPL libraries out there, like GSL and FFTW, and use published GPL algorithms without restrictions.
And I wrote a Python extension framework, so anyone can extend AfterNight without touching the C++.
An extension is a package with a manifest and one Python class: it declares its parameters, the host
draws the panel, and its execute method receives the source and destination images, the mask and
a progress handle. The bundled demos go from a one-class filter to a workflow with its own window.
Every process is built the same way: a lot of research, full tests, and then I use it on my own data, many times, and ask myself: Is this useful? Is it enough? How can I improve it? Why does this process matter in a common workflow?
Four years later
AfterNight is the result of four years of work. The first three were by hand: about 130,000 lines of C++ by September 2025.
Then came AI, and it cut both ways. On AfterNight it helped a lot: full test suites, UI improvements, documentation, finding bugs, analyzing crash dumps, some performance analysis, consolidating the CI/CD infrastructure and, this year, work on the third engine. It sped up everything that was left to do.
The history shows it. These are the commits on main, merges not counted, up to 22 October 2026:
| Year | Commits |
|---|---|
| 2022 (from 16 October) | 44 |
| 2023 | 438 |
| 2024 | 538 |
| 2025 | 754 |
| 2026 (to 22 October) | 2,588 |
| Total | 4,362 |

The first commit made with a coding agent is from 24 September 2025. The ten months of 2026 have more commits than 2022 to 2025 together (2,588 against 1,774). A commit counts a change, not the work behind it, so read the chart as the shape of four years rather than a measure of effort. I counted them with:
git log origin/main --no-merges --date=format:%Y --format=%ad \
| sort | uniq -c
The code grew the same way: from those 130,000 lines in September 2025 to 784,000 lines of product code on 22 October, with another 504,000 lines of tests, fuzz targets and benchmarks behind it.
But AI also lets anyone build their own application without a background in software engineering, and new tools appear every week. I have nothing against it: it lets people build the software they always wanted. I’ll admit, though, that it stings a little after thousands of hours of doing it the hard way.
What hasn’t changed is who decides. The architecture and every design are mine, agents work from them, and nothing they write stays unless it is tested and does at least what it replaces. I can still explain every algorithm and every module in AfterNight, including the ones an agent wrote.
What didn’t work
The first engines. The first one, in October 2022, loaded images through libvips. A month later it was gone: it fought me on floating-point TIFFs, so I wrote the codecs myself, slower at first. In August 2023 the image class was next: pixels were stored interleaved, one plane per channel was much more efficient, and every process had to be ported. The third rewrite finished on 21 October 2026. The engine had grown into one static facade, the image class mixed storage, ownership, conversion, metadata and processing state, and too many operations converted every sample to double, computed, and converted back. The replacement was built as a sibling engine, measured against the old one, and cut over in one commit. The GUI had its own rounds: the real-time preview pipeline was rewritten in 2023 and again, asynchronous, in 2024, when the windows also moved to a docking system. Each version was better than the one before, and none of the early ones survived.
Waiting until it was ready. My one real regret is being too much of a perfectionist and not releasing AfterNight two years ago. It wasn’t as mature as it is now, but it had enough to earn its place, and maybe to attract early contributions from other developers. I always felt it wasn’t the time, that it wasn’t ready… and here we are. That one is on me.
Next
AfterNight isn’t public yet. The repository is being cleaned up for release, and after the lesson above I’m keeping that list short. It will land in a crowded field, next to commercial and free tools with huge user bases, but I think some of you will love it.
It took almost all my free time for four years. Countless games and movies were postponed, and I enjoyed every hour in front of the computer. Digging into the math of calibration, registration and the rest of the usual image-processing algorithms taught me more about astrophotography than anything else, and this series is where I’ll write it down: one stage of the pipeline per post, with the code and the numbers, collected in Building AfterNight.
So, why did I build a C++ astrophotography suite from scratch? Because I could, and because it was the best way to learn astrophotography and image processing.
