QIAOPANG.COM · SELECTED ESSAYS (2013–2026) · 260 ESSAYSBrowse Chronologically (2013 → 2026) ↗
QiaoPang · Programmers LifeSelected Essays · Systems, Craft & Agentic Era
Timeline ↗

The One-Person Company: Building a Private Package Registry on Serverless Architecture

The One-Person Company: Building a Private Package Registry on Serverless Architecture

The skilled warrior wins without feats of cunning, without a name for wisdom, without glory for courage. — Sun Tzu

Preface: This is the fourth installment of the “One-Person Technology Company” series. The OPC (One Person Company) concept is hot right now, so I figured I’d give it a taste — to see what actually comes out when you seriously use your weekends to do the kind of work that only a real technology company could pull off. This doesn’t mean I’m going full-time founder. I consider myself a perpetual entrepreneur; a nine-to-five was never my constraint. What I want from this process is to understand the boundaries of AI — and my own.

The series documents the whole journey of building a complete technology stack from scratch — from infrastructure, to networking and runtime, to core frameworks, to application services. This is not a tutorial; it’s a field journal with the thinking process left in.

The first three covered a security framework, a multi-tier k8s architecture, and a serverless application framework. Today we tackle something many indie developers overlook but can’t avoid once the codebase grows: the private package registry.

If you’re single-handedly running a tech company, or a team of three to five juggling several projects, sooner or later you’ll hit these situations: you wrote a general-purpose utility library and want to reuse it across three or four projects; you’ve encapsulated some internal business logic that isn’t fit for open source but needs to be shared across projects; your CI/CD pipeline needs to pull private dependencies. What you need at that point is a private package registry.

Sounds simple, right? Just install an off-the-shelf solution and call it a day?

Not so fast. But there’s good news: in the AI era, “building a private registry from scratch” has gone from “scares off 90% of developers” to “doable in half a day.”

Why Do You Need a Private Registry?

You might say: just throw the code in a private Git repo and reference it as a Git dependency — done.

That works as a stopgap early on. Cargo supports git = "https://..." dependency declarations, and NPM accepts Git URLs. But once the codebase grows, the pain arrives:

First, version management is essentially nonexistent. Git dependencies pin you to a particular commit or branch, with no semantic versioning (semver) constraints. When a dozen internal libraries depend on each other, running without version numbers turns into a disaster scene within minutes. You change library A’s API and libraries B, C, and D all blow up at once — and you have no idea which version still works.

Second, build times degrade visibly. Every build pulls the full source from Git, and compile time grows linearly with the number of dependencies. A proper package registry serves prebuilt artifacts, and build speed improves by an order of magnitude.

Third, the ecosystem toolchain breaks outright. Cargo’s and NPM’s tooling (version resolution, dependency tree analysis, security auditing) is all designed around the registry protocol. Using Git dependencies means bypassing the entire ecosystem, and a whole arsenal of useful tools simply stops working.

So once your internal codebase exceeds five or six interdependent libraries, a private registry goes from “nice to have” to “survival requirement.”

The Cost Dilemma of Existing Solutions

OK, the requirement is clear. What’s out there?

Put yourself in the shoes of a one-person company or a three-to-five-person team, faced with these options:

Hosted SaaS: Cloudsmith, Artifactory Cloud, and the like. The feature set is complete, but the pricing isn’t cheap either. For a small team doing a few hundred publishes and a few thousand downloads a month, paying tens to over a hundred dollars monthly is genuinely unnecessary. And many options don’t support both Cargo and NPM, so you might end up buying two subscriptions.

Self-hosted open source: Verdaccio (NPM) or Kellnr (Cargo). Looks free, but you have to keep a server running around the clock. The cheapest EC2 instance still costs a dozen-odd dollars a month, and once you add storage, bandwidth, and the hidden costs of operations, the real bill isn’t low at all. Worse, you have to maintain it. The server goes down, and every project’s CI/CD collapses at once. In a one-person team, the cognitive load of operating a stateful server is genuinely more than one person can bear.

GitHub Packages / GitLab Packages: Decent, but limited. GitHub Packages’ Cargo support has been languishing in experimental status for ages; NPM support is passable but locks you into the GitHub ecosystem. If your infrastructure isn’t on GitHub, integration costs are steep.

Which raises the soul-searching question: is it possible to build a private registry with near-zero operations, under $10 a month, that supports multiple package managers at once?

The answer: yes. With serverless architecture — and we happen to have just finished the operon framework.

Back to First Principles: What Does a Package Registry Actually Need?

Before writing any code, let’s peel back the shell of a package registry and see what’s actually inside.

From first principles, a package registry needs — and only needs — these capabilities:

  1. Authentication and authorization: figure out “who you are” and “what you can do”
  2. Package storage and retrieval: upload artifacts, download artifacts
  3. Metadata indexing: let the package manager know what packages exist, which versions, and how dependencies relate
  4. Version management: support semver constraints, yanking, and related operations

That’s it. No complex real-time communication, no long-lived connection state, no compute-intensive tasks. Every operation is a short-lived, stateless HTTP request-response.

Isn’t that serverless architecture’s comfort zone?

And look closely at those four requirements: none of them is hard because of “creativity” — they’re hard because of “precisely implementing protocol details.” How each field in Cargo’s sparse index protocol is assembled, what the JSON structure of an NPM package document looks like, how the HTTP headers should be set… you can figure all of this out by reading RFCs and source code, but grinding through it by hand is tedious and error-prone. Which is exactly the kind of work AI excels at. Feed the RFCs and protocol specs to Claude Code, and it translates them into runnable code quickly and accurately. You only need to own the architectural decisions and edge cases; the grunt work goes to the AI.

This insight matters: AI hasn’t changed what you need — it has completely changed what you can do. In the past, the ROI on a self-built private registry never penciled out; just grinding through the protocol specs of two package managers was enough to do you in. With AI, the distance from spec to implementation has been dramatically compressed, and the feasibility of building it yourself has suddenly shot up.

Map those four requirements onto AWS managed services:

The One-Person Company: Building a Private Package Registry on Serverless Architecture — architecture diagram

  • S3 stores binary artifacts and index files — unlimited capacity, pay per use
  • DynamoDB stores package metadata, user info, and audit logs — on-demand billing, zero traffic means zero cost
  • Lambda handles all API requests — pay per invocation, nothing when idle
  • CloudFront serves as CDN and request entry point — edge caching maxed out to reduce Lambda invocations
  • JWT for authentication — pure signature verification, no database touched

Every component follows a “pay for what you use” model. At small-team volumes, the monthly bill can be squeezed into single digits.

Overall Architecture Design

Let’s lay out the full architecture. The system’s core design principles:

  • Zero-ops serverless: not a single server to worry about — everything is AWS managed
  • A single Lambda function: one Rust binary handles every route (Cargo + NPM + auth)
  • Stateless authentication: JWT tokens self-verify via Ed25519 signatures, no database touched
  • Edge acceleration: Lambda@Edge validates JWTs at CloudFront edge nodes, so illegitimate requests never reach the origin
  • Extensible protocols: the auth/storage/audit layers are shared; each package manager’s protocol handling plugs in and out

The overall request flow looks like this:

The One-Person Company: Building a Private Package Registry on Serverless Architecture — architecture diagram

A few of these architectural decisions deserve a closer look.

Why JWT Instead of Traditional Tokens?

This is a decision that moves everything downstream. Traditional private registries (Artifactory, for instance) use opaque tokens: the client sends a token, and the server looks up the corresponding user and permissions in a database. The problem with this model is that every request hits the database.

Under serverless architecture, that means every cargo build — which may trigger dozens of index lookups and download requests — produces dozens of DynamoDB reads. You get the latency and the bill. A double whammy.

MORE IN AI & Autonomous Agents

Further Reading in This Column

View all essays in “AI & Autonomous Agents” →