DEV Community

Cover image for I Became a MinIO Refugee, So I Built a Replacement with AI
mojatter
mojatter

Posted on

I Became a MinIO Refugee, So I Built a Replacement with AI

I built an alternative and named it S2 (Simple Storage).
https://github.com/mojatter/s2

More details below, but here's a quick look β€” it works almost like MinIO via docker compose:

services:
  s2:
    image: mojatter/s2-server
    ports:
      - "9000:9000"
    environment:
      S2_SERVER_USER: myuser
      S2_SERVER_PASSWORD: mypassword
      S2_SERVER_BUCKETS: assets,uploads
    volumes:
      - s2-data:/var/lib/s2

volumes:
  s2-data:
Enter fullscreen mode Exit fullscreen mode

Why I Built It

I've been using MinIO across several projects, but it went into code freeze and I wasn't comfortable staying pinned to a specific version indefinitely.

What I Learned Pairing with AI

I know most of you are already getting the most out of AI/LLMs β€” I'm a late starter here.

I kicked things off casually using Google Antigravity (an agent-first IDE powered by Gemini 3.1 Pro) with no paid plan. I wrote the initial codebase myself, and leaned on it heavily for English documentation since that's not my strong suit.

I pushed through to the first commit with Antigravity, but hit the free tier limits pretty quickly. I'd paid for Gemini once before and blew through $200 in two days, so I switched to Claude Code to keep going.

I fully intended to write all the Go code myself β€” but Claude Code is remarkably capable. Give it a direction and the code comes back almost exactly as you envisioned.

At first I let it handle git commit. Then before I knew it, I was handing off git push and PR creation too. By that point, I'd basically stopped writing code myself.

As I kept delegating, it suggested creating a docs/api-audit.md. I had no idea what that was β€” apparently it's standard practice in the OSS world. That kind of discovery kept happening, and then it started proposing API redesigns. When I dug into the reasoning, every point made sense. It felt like a new hire who was honestly more capable than me had just joined the team.

Eventually my workflow became: describe what I want at a high level, skim the PR, click merge.

I'd figured it would take a month of working in spare moments to get something functional. Instead, something better than I'd planned was done in a matter of days.

I used to picture myself writing code well into old age. Turns out that may not be how things go. πŸ˜„

About S2

Let me get to the actual pitch.

S2 offers both a MinIO-like server and a general-purpose storage client interface.

MinIO-like S2 Server

It covers the essentials: multipart upload, SigV4 authentication, presigned URLs. Advanced features like ACL and versioning aren't supported, but for "I just want to use an S3 client as-is in local dev and staging" use cases, it holds up well.

Swapping out production S3 or MinIO is just an endpoint URL change.

If you have Docker, one line gets you a running server with a web console at localhost:9000:

docker run --rm -p 9000:9000 mojatter/s2-server
Enter fullscreen mode Exit fullscreen mode

Web Console

General-Purpose Storage Client: s2env

Backends are swappable via config, giving you something close to Laravel's Storage facade. Switch between S3 in production and osfs locally without touching your code.

// s2.json
{
  "assets": { "type": "osfs", "root": "/var/data" },
  "prod":   { "type": "s3",   "root": "my-bucket" }
}

// Same interface regardless of backend
storages, _ := s2env.Load(ctx, "s2.json")
assets := storages["assets"]
assets.Put(ctx, s2.NewObjectBytes("hello.txt", []byte("hello")))
Enter fullscreen mode Exit fullscreen mode

For testing, swap in memfs and you can test object storage code without spinning up Docker at all.

strg, _ := s2.NewStorage(ctx, s2.Config{Type: s2.TypeMemfs})
// Same code as production β€” no Docker needed
Enter fullscreen mode Exit fullscreen mode

Wrap-up

I became a MinIO refugee and built a replacement with AI. Here's what I found:

  • The speed and accuracy were remarkable β€” I ended up handing almost everything over.
  • It gave me new insights along the way and I genuinely learned things.
  • The end result was better than what I originally had in mind.

It's a fascinating time to be building software. Give S2 a try!

Credits

The header image was generated with Google Gemini. It includes the Go Gopher mascot, originally designed by RenΓ©e French and licensed under CC BY 3.0.

Top comments (0)