Hosting images for a static site without bloating your Git repository

Written by Codemzy on November 3rd, 2021

All the best static site providers give you continuous deployment from Git. But what about your images files? Should you store them in your Git repository too? Noooo! Don't do it! Here are some solutions for image storage without bloating your repository.

Static sites are a great way to publish high performing landing pages and blog posts. And, with the rise of the JAM stack (thanks Netlify!), almost any kind of website or service can have a static front-end.

And services like Netlify make it super easy to wire up your GitHub repository and launch a static site in minutes. We are living magical times!

But maybe, like me, you’ve wondered where to host your images. Because any decent marketing site or blog post is going to need a picture or a few now and again! Should you just stick image files in your repository too?

No! Don’t do it!

At least, not if you need to store a lot of images. And not if you are using a Cloud IDE or if you will be regularly cloning your repository on different machines.

So, every developer has the full change history on their computer. And changes in large binary files cause Git repositories to grow by the size of that file every time the file is changed (and that change is committed). That means it will take ages to get the files. And if you do, it will be difficult to version and merge the binaries.

- Chuck Gehman (Perforce) How Git LFS Works

I’ll be honest, this is a mistake I made a few years ago. And at first, everything continued running smoothly.

But image files will bloat your repository. And when you need to clone it or use a cloud development environment (like Gitpod), everything will take so much longer. You’ve got all those images to download every time.

So what should you do instead?

Here are a couple of options to consider.

Static Storage

This blog post is about static sites, and I love static sites, so can we find a static solution to this problem? Yes, we can!

This blog post isn’t sponsored by Netlify, but it is my static hosting provider of choice. And there’s a really simple way to host your images on Netlify without bloating your repository. Actually, there are a couple of ways*.

Just because you’re keeping images out of Git, doesn’t mean you can’t still use Netlify to host them. You can use manual uploads.

This is how I host the image files for this website and a couple of others. It works well, especially if you don't add new images very often. For example, I don't often change images on my blog posts, I just add images on new posts.

First, you will need to create a new Netlify site, just for the images. And because you won’t be using Git, you’re going to be doing a manual deployment. It doesn’t get simpler than this, you drag the folder with your images in it, and before you know it, they are live on the web.

netlify manual deploy

If you already have your domain on Netlify (for your main site) you can easily align a custom domain for your images site. Like or Then the URL to your images matches your domain and you look super professional.

So that you don't run into any CORS issues, you can also pop this in a _headers file in the root of the images folder, to avoid any issues using the images on other domains/subdomains.

# applies to all paths
  # allows cross-origin requests
  Access-Control-Allow-Origin: *

Note: when you need to add more images or update a file, you'll have to manually drag the entire images folder to upload the whole thing again. But don’t worry, Netlify is smart and will only process and upload the new or changed files.

There are other static site providers available but not all of them let you manually upload your content. I couldn't find a way to manually upload static images to Vercel or Render. You can do it on Glitch by uploading files to the assets folder. And you can upload a directory to Firebase Hosting via a CLI.

If you are using a static provider without manual uploads, or have more complex needs, you can use object storage to store your image (and other files).

*you can also use a GitHub extension called Git Large File Storage with Netlify's Large Media. I've never taken this route and it does have some limitations to be aware of.

Object Storage

Maybe you have user-uploaded images on your site or generate images dynamically, or somewhere to upload your images via API calls.

This is where the concept of a static site gets a little… blurry. But most static providers including Netlify, Vercel, Firebase and AWS let you run serverless functions. So you can call other services based on user actions.

Or maybe you just want to upload images one at a time or have more control of the settings on each file. Again, object storage might be a good solution for you.

AWS is the big player in this space with Amazon S3, but you will need to spend a bit of time getting to know the system. Firebase / Google Cloud Storage also has object storage available. And so does Azure.

DigitalOcean Spaces is great because it comes with fixed pricing and a decent chunk of bandwidth. Cloudflare has also launched an object storage solution Cloudflare R2 Storage.

I've used DigitalOcean Spaces extensively, and you can manually upload files using the web interface, and create functions to do this from your code using your backend language of choice. If you want to give it a try and are new to DigitalOcean, you can use my DigitalOcean referral link to get a $200 credit.

Proxy Image Paths

If you use an external service, your images might be on a different domain. Even if you use the same service, you might not want your image paths to be on a subdomain. You might want images to be on an img directory URL, for example.

Whichever solution you choose, you can proxy your domain in your static site settings so it looks legit. It only takes one line of code.

Here’s how you would do it on Netlify as a Redirect in a _redirects file.

# img redirects
/img/* 200

Or you can do it in your netlify.toml file.

## This rule redirects to an external API, signing requests with a secret
  from = "/img/*"
  to = ""
  status = 200

And here’s how you would do it on Vercel as a Rewrite inside vercel.json.

  "rewrites": [
    { "source": "/img/:path*", "destination": "*" },

I use a mixture of manual uploads on Netlify and DigitalOcean Spaces for user-uploaded content for my image needs. Hopefully, now you have a few ideas for your image hosting requirements!