Building Things, Understanding Systems, and Staying in Control
I've spent a lot of time building software, experimenting with infrastructure, and working on projects that sit somewhere between application development and systems engineering. Looking across the things I've worked on, there's a fairly consistent theme: I like understanding how things work, finding the parts that are missing, and building the tools needed to make them work better.
I'm a software engineer based in Sydney, Australia. Most of my professional work has involved backend systems, APIs, integrations, and infrastructure, but my interests extend well beyond the usual boundaries of application development. I enjoy working on everything from web services and developer tooling to networking, security, operating systems, and the occasional experiment that probably could have been solved with an existing tool but wouldn't have been nearly as interesting.
I like knowing what's underneath the abstraction
Modern software development is built on layers of abstraction. We have frameworks for applications, runtimes for programming languages, orchestration platforms for infrastructure, and managed services for just about everything else.
These abstractions are useful. I don't want to reinvent every wheel, and I certainly don't think everything needs to be written from scratch.
But I do think there's value in understanding what happens underneath them.
That interest is one of the reasons I've spent so much time working with Cosmos, an open-source operating system development toolkit I've contributed to since 2016. Working on operating systems forces you to think about problems that application developers can often ignore: memory management, execution models, assembly loading, native code, threading, and the boundary between hardware and software.
More recently, I've been interested in the next generation of Cosmos and what it takes to build out a proper userland. That means thinking about platform-independent memory paging interfaces, native threads, executable loading, and system calls.
These aren't necessarily glamorous problems. They're foundational ones. Getting them right makes everything built on top of them possible.
Sometimes the best way to understand a system is to find the point where the abstraction stops helping.
Open source should be sustainable
I'm a strong believer in free and open-source software. Not simply because the source code is available, but because users should have meaningful control over the software they depend on.
That includes being able to inspect it, modify it, host it themselves, and move away from a provider when they need to.
Vendor lock-in is a particularly frustrating part of modern technology. Too often, a service starts out as a convenient solution and gradually becomes a dependency that is difficult or expensive to replace. The problem isn't that commercial services exist. It's that the cost of leaving them can become unreasonable.
I want to help build alternatives.
Through PunkSky, I've been exploring what it looks like to build a business around open-source software without abandoning the principles that make it valuable. Open source and commercial sustainability aren't mutually exclusive. There are ways to fund development through paid features, support, and services while keeping the underlying software accessible.
In my view, the important distinction is between charging for the work required to build and maintain software and making customers dependent on an artificial restriction.
I want to build things people choose to use because they work well, not because leaving would be too difficult.
Infrastructure is software, too
One of the things I enjoy most is working on the infrastructure that other software depends on.
Networking, routing, identity, storage, deployment, and security can sometimes be treated as separate operational concerns. I tend to see them as extensions of software engineering.
An infrastructure problem is still an engineering problem. It has interfaces, invariants, failure modes, performance characteristics, and trade-offs. It deserves the same attention to design and maintainability as an application does.
That's part of the motivation behind PunkProxy, an edge HTTP proxy project that brings together features such as automatic certificate management, per-zone configuration, and the OWASP Coraza Web Application Firewall.
A project like this involves more than forwarding HTTP requests. It raises questions about configuration boundaries, security policy, certificate lifecycle management, deployment models, and how to make the system useful without turning it into an operational burden.
I'm also interested in self-hosting and building infrastructure that can be understood and maintained by the people operating it. That means exploring Linux configuration management, identity integration, mail infrastructure, routing, and ways to manage services through code and reproducible configuration.
I don't believe every organisation needs to run everything itself. Managed services have legitimate advantages. But self-hosting should remain a viable option, rather than an increasingly obscure capability reserved for a handful of specialists.
Developer tooling should make difficult things easier
I also enjoy building the tools that make other developers more productive.
A lot of engineering time is spent working around limitations in existing tooling: writing repetitive integration code, maintaining configuration in multiple places, translating between representations, or dealing with abstractions that don't quite fit the problem.
Code generation, strongly typed interfaces, and compile-time constraints are recurring interests of mine because they can move entire categories of errors out of runtime and into development.
In backend systems, that might mean generating API clients, making database relationships explicit in the type system, or creating abstractions that enforce tenant boundaries and audit requirements.
In infrastructure, it might mean making a service configurable through declarative definitions rather than a collection of undocumented conventions.
The common goal is to make the correct approach easier to implement and the incorrect approach harder to express.
I don't think abstraction is inherently good or bad. A useful abstraction captures a real constraint or removes meaningful complexity. A bad one simply moves the complexity somewhere less visible.
Knowing the difference is a big part of engineering.
I prefer owning the entire problem
I tend to gravitate towards projects where several layers of a system meet.
A networking problem might turn into a routing problem. A routing problem might turn into a deployment problem. A deployment problem might reveal that the configuration model itself is wrong.
I enjoy following those connections rather than treating each layer as someone else's concern.
That doesn't mean working in isolation or refusing to use existing solutions. Quite the opposite: good engineering requires knowing what to reuse, what to integrate, and what is worth building yourself.
But I like being able to follow a problem far enough to understand its actual cause.
This is also why I have an interest in self-hosted developer platforms, distributed systems, message queues, identity and access control, and infrastructure that can run across different environments. These systems are interesting because their design decisions have consequences beyond a single function or service.
Reliability, security, observability, and operational simplicity are not features you can bolt on at the end. They emerge from decisions made throughout the system.
Not everything needs to be a startup
Some of my projects are commercial in nature. Others are long-running open-source efforts or experiments that exist because I want to understand something better.
I think there's value in that distinction.
Not every useful project needs a market analysis, a monetisation strategy, or a roadmap designed around growth. Sometimes the value is learning how a system works. Sometimes it's solving a problem that affects a small group of people. Sometimes it's contributing to a project that has been around for years and helping it move into its next stage.
Cosmos is a good example of the long-term side of software development. Contributing to a project over many years gives you a different perspective from building something new every few months. You see how assumptions accumulate, how technologies change, and how difficult it can be to evolve an established system without losing what made it useful.
I want to keep making room for both kinds of work: projects that need to become sustainable products and projects that are valuable simply because they advance the state of the art or help someone solve a real problem.
What comes next
I'm interested in continuing to work across backend engineering, systems programming, networking, security, and open-source infrastructure.
That includes improving the foundations of Cosmos, developing tools through PunkSky, experimenting with new approaches to developer tooling, and finding better ways to build and operate software without unnecessary dependencies.
I'm particularly interested in the space between application development and systems engineering. It's a place where a practical product requirement can lead to a question about runtime behaviour, network protocols, memory management, or operating system design.
Those connections are what keep the work interesting.
I don't have a single grand theory about how all software should be built. Different problems call for different tools, and there are plenty of situations where a conventional solution is the right one.
But I do have a few principles I keep coming back to:
- Understand the system you're building on. Abstractions are useful, but knowing their limitations makes you a better engineer.
- Prefer open systems. Users should have a reasonable degree of control over the software they depend on.
- Build for maintainability. The code that ships is only part of the product; operating and evolving it matters just as much.
- Automate the repetitive work. Good tooling should eliminate entire classes of mistakes, not just save a few keystrokes.
- Keep experimenting. Some of the most useful ideas come from projects that start as curiosity rather than a commercial requirement.
Ultimately, I want to build software that gives people more control over their technology, makes complicated systems easier to work with, and stands up to the reality of being used and maintained over time.
There's always another layer to explore, another limitation to work around, or another tool that could be built better.
That's what makes this work interesting to me, and it's probably what will keep me doing it for a long time.