DEV Community

Cover image for NextJS Gallery now with Vite
Osinachukwu Nnanna
Osinachukwu Nnanna

Posted on

NextJS Gallery now with Vite


What I learned porting the Next.js Gallery to a Vite SPA

I’ve always admired the Next.js Gallery template (https://nextjsconf-pics.vercel.app/). It’s a beautiful
piece of engineering, but it relies on a lot of "framework magic" from things like next/image and server-side functions that just work, but are
sometimes hard to peek inside of.

I decided to try porting it to a Vite SPA (Single Page Application). Not because Vite is "better," but because I wanted to see if I could
replicate those high-end features using simpler, more transparent building blocks like Bun/NodeJS, Sharp, and Supabase.

Here’s what that process looked like.

The Goal: High Performance without the "Magic"

The original template feels great because of two things: layout stability (no jumping around) and those smooth "blur-up" image loads. In a
standard SPA, you usually lose these because you don't have a server processing the images on the fly.

To get around this, I moved the "thinking" to a build-time script.

Understanding the Metadata
Instead of asking a server to resize images while the user waits, I wrote a script (src/scripts/buildImages.ts) that runs once before the app
even starts.

I used Sharp to do the heavy lifting. It opens the images, finds their width and height, and generates a tiny (10px) base64 string. This string
becomes the "blur" you see while the high-res photo is downloading.

Storing this in a static images.json file felt like a "low-tech" but effective way to get that premium feel without needing a complex backend.

Building the "Admin" in the Terminal
I realized that for a personal gallery, I didn't really need a web dashboard. I just wanted to drop files in a folder and have them appear.
Also if you use in the uploads/ directory that is created in a links.txt, by providing the image links in this folder, the delimeter/separation would just be a New Line/Enter, once the scipt starts and sees links there it temporarily downloads the files, converts them and then pushes them to the bucket.

I built a small CLI tool (src/scripts/admin.ts) that handles the "boring" parts:

  • Optimizing images to WebP so they don't take up too much space.
  • Uploading them to Supabase.
  • Setting up the initial user.

It’s not flashy, but it made the workflow feel a lot more "local" and manageable.

What I can try Next? (The "Adapter" Idea)

Right now, the project is tied to Supabase. It works well, but I’ve been thinking about how to make it more flexible.

The next step in this experiment is to pull the Supabase logic out and create Adapters. The idea is that you could use the same gallery UI but
point it at an S3 bucket, Cloudflare R2, or even just a local folder on your computer.

UI

Final Thoughts

This project was a great way to demystify how modern galleries work. By stepping away from the "all-in-one" frameworks for a moment, I got to
see exactly how image metadata and placeholders come together to create a smooth user experience.

Would you like to self-host a gallery website, try it out. There are a little less CVE's to worry about

If you’re interested in the code or want to try setting up your own, I’ve put everything on GitHub:

=> Vite-Gallery on GitHub (https://github.com/osinnanna/vite-gallery)
=> NextJS Template on Vercel and demo.

I’m still tinkering with the adapter logic(local folder inst. of Supabase and other options), so if you have ideas on how to make this more "pluggable," I'd love to hear them.

Top comments (0)