DEV Community

Cover image for How to Use minio-go for S3-Compatible Storage in Go
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on • Edited on

How to Use minio-go for S3-Compatible Storage in Go

Hello, I'm Maneshwar. I'm working on FreeDevTools online currently building **one place for all dev tools, cheat codes, and TLDRs* — a free, open-source hub where developers can quickly find and use tools without any hassle of searching all over the internet.


minio-go (v7) is a lightweight, idiomatic
Go SDK for Amazon S3–compatible object storage, built by MinIO. It's fast, minimal, and supports core S3 API operations like buckets, object uploads/downloads, pre‑signed URLs, notifications, lifecycle, and more—without the bloat of AWS’s SDK (GitHub, pkg.go.dev).

Quickstart: Uploading a File

package main

import (
  "context"
  "log"
  "github.com/minio/minio-go/v7"
  "github.com/minio/minio-go/v7/pkg/credentials"
)

func main() {
  ctx := context.Background()
  endpoint := "play.min.io"
  accessKey := "Q3AM3UQ867SPQQA43P2F"
  secretKey := "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"
  useSSL := true

  client, err := minio.New(endpoint, &minio.Options{
    Creds:  credentials.NewStaticV4(accessKey, secretKey, ""),
    Secure: useSSL,
  })
  if err != nil {
    log.Fatalln(err)
  }

  bucket := "testbucket"
  err = client.MakeBucket(ctx, bucket, minio.MakeBucketOptions{Region: "us‑east‑1"})
  if err != nil {
    exists, serr := client.BucketExists(ctx, bucket)
    if serr == nil && exists {
      log.Printf("Bucket %q already exists", bucket)
    } else {
      log.Fatalln(err)
    }
  } else {
    log.Printf("Created bucket %q", bucket)
  }

  info, err := client.FPutObject(ctx, bucket, "hello.txt", "/tmp/hello.txt", minio.PutObjectOptions{
    ContentType: "text/plain",
  })
  if err != nil {
    log.Fatalln(err)
  }
  log.Printf("Uploaded %q, size %d bytes\n", info.Key, info.Size)
}
Enter fullscreen mode Exit fullscreen mode

This example connects to MinIO’s play.min.io, creates a bucket, and uploads a file—just 25 lines of Go (GitHub).

Other Powerful Features

  • Bucket listings & deletions
    Methods: ListBuckets, RemoveBucket, ListObjects, RemoveObjects (MinIO, GitHub, GitHub).

  • Object operations
    Download (GetObject / FGetObject), stat (StatObject), copy (CopyObject), multipart uploads, and range/seeking all supported (GitHub).

  • Pre-signed URLs
    Generate authenticated URLs for upload/download/HEAD operations—ideal for client-side file sharing: PresignedGetObject, PresignedPutObject, PresignedPostPolicy, etc. (GitHub, MinIO).

  • Bucket policies / notifications / lifecycle
    Set/get bucket policy and notifications via SetBucketPolicy, ListenBucketNotification, lifecycle rules, tags, and more (MinIO).

Tips & Tricks

  • Credentials: Support for static (accessKey/secretKey), as well as AWS IAM, STS, and custom credential loading.
  • Secure by default: SDK uses HTTPS unless explicitly set to Secure: false.
  • Compatibility: Works with AWS S3, Ceph, GCS (via V2), OpenStack Swift, Riak CS, and any S3-compatible endpoint (MinIO, GitHub, Reddit).
  • Performance: Well-suited for high-throughput use cases like ML pipelines and distributed systems (GitHub, Wikipedia).

Deeper Example: Listing Objects

objectsCh := make(chan minio.ObjectInfo)
go func() {
  defer close(objectsCh)
  for object := range client.ListObjects(ctx, bucket, minio.ListObjectsOptions{
    Prefix:    "logs/",
    Recursive: true,
  }) {
    if object.Err != nil {
      log.Println("Error:", object.Err)
      continue
    }
    objectsCh <- object
  }
}()

for obj := range objectsCh {
  log.Printf("Found object: %s (size %d bytes)\n", obj.Key, obj.Size)
}
Enter fullscreen mode Exit fullscreen mode

This stream-based listing demonstrates idiomatic Go channel use and is included in the official examples (GitHub).

Wrap-up

minio-go offers simplicity and power: just a few imports and you have full S3 capability. It shines in:

  • Storage integration for Go apps
  • Microservices needing pre-signed uploads
  • Cloud-native workflows with notifications, tags, lifecycle rules

Whether you're building an image uploader, analytics pipeline, or backup tool, minio-go has you covered.

Next Steps

  • Explore the full API reference: bucket policies, lifecycle, encryption options (MinIO).
  • Check out more advanced examples: multipart uploads, encryption, streaming (GitHub).
  • Integrate with AWS S3 or self-hosted MinIO for production workloads.

FreeDevTools

I’ve been building FreeDevTools.

A collection of UI/UX-focused tools crafted to simplify workflows, save time, and reduce friction in searching tools/materials.

Any feedback or contributors are welcome!

It’s online, open-source, and ready for anyone to use.

👉 Check it out: FreeDevTools
⭐ Star it on GitHub: freedevtools

Let’s make it even better together.

Top comments (0)