You know how it goes: you’re mocking up a quick UI and you need some placeholder images—maybe a hero banner here, a product image there. Sure, there are plenty of placeholder image generators out there, but I’ve often run into two recurring issues: they either don’t offer enough customization or they’re littered with ads and distractions. I wanted something lightweight, straightforward, and perfectly tailored to my own prototyping needs. So, over the course of a weekend, I put together my own customizable SVG placeholder generator: placeholder.griffen.codes.
Yes, I’ll admit there’s a glut of these tools already. But many are static, require you to memorize URLs, or feel a bit too… commercialized. I’m no stranger to grabbing random placeholder images from other sources, but I wanted more control and zero clutter. This was my attempt to scratch that itch, and honestly, it was just a fun way to see how quickly I could stand something up using the latest tools in my workflow.
I’ve been reaching for SVGs in prototypes for a while now—being vector-based, they’re crisp at any size and super easy to edit. Change a color, swap out some text, tweak a pattern: it’s all right there in the code. No need for massive raster files that slow down the page or generic stock images that don’t represent the layout I’m trying to visualize.
This project came together rapidly thanks to a few key pieces:
The result? A tool that feels lean, clean, and free of intrusive ads—and I managed to build it in just a handful of hours.
At placeholder.griffen.codes, you can configure just about every aspect of your placeholder:
<svg>
code directly, download the file, or copy a Base64-encoded version to embed inline.The code is pretty straightforward. One neat trick is the ability to convert files to Base64 if that’s something you want to do. For instance, here’s a snippet from the code handling file conversions:
export function fileToBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
const base64String = reader.result as string;
resolve(base64String);
};
reader.onerror = () => {
reject(new Error("Failed to read file as Base64"));
};
reader.readAsDataURL(file);
});
}
While the core functionality doesn’t rely heavily on this feature right now, it’s something I’m exploring for more flexible background options down the road.
It’s as simple as:
This project was never about reinventing the concept of placeholder images. Instead, it’s a personal spin on an existing idea—something cleaner, more customizable, and better aligned with how I prototype. The kicker is how fast it came together. Thanks to modern frameworks, UI kits, and a little AI nudge, I could turn an idea into a working tool over the weekend.
If you find it useful, or if you have ideas on how to improve it, I’d love your input. Check out the GitHub repo: github.com/gfargo/placeholder.svg and feel free to open an issue or submit a PR.
Enjoy creating your placeholders, and may they always be as unique as your mock-ups.