jekyll_picture_tag turns one image into responsive markup
Easy responsive images for Jekyll.
At a glance
- What is it?
- jekyll_picture_tag is a Ruby gem that generates the cropped, resized and converted image files for a Jekyll site along with the corresponding markup in several formats, handling art direction and resolution switching from one template tag and a little YAML. It is BSD-3-Clause licensed and switched its image backend from ImageMagick to libvips in version 2.0.
- Who is it for?
- jekyll_picture_tag suits a Jekyll site that needs proper responsive images without hand writing picture elements, srcset lists and CSS for every breakpoint, since the gem generates the image files and the markup together and supports art direction where different crops are wanted per breakpoint. It is the wrong tool if your site is not Jekyll, and it is the wrong tool if you cannot run libvips or ImageMagick on the build machine, because the image work happens at build time.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 41 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it is aimed at
The README opens with a short argument for why responsive images are worth automating, and it is worth restating because it explains what the gem is for.
The performance case is that the fastest sites are static sites, but if you plonk a 2mb picture of your dog at the top of a blog post you throw it all away. Responsive images allow you to keep your site fast, without compromising image quality.
The design case is separate and often more important. Your desktop image may not work well on mobile, regardless of its resolution. We often want to do more than just resize images for different screen sizes, we want to crop them or use a different image entirely.
That second point is what separates this from a set of resized thumbnails. A responsive image implementation needs at least two distinct mechanisms: resolution switching, where the browser picks a smaller file for a smaller screen, and art direction, where the browser picks a different crop or a different image for a different screen. The second cannot be done with a srcset alone, which is why a picture element and CSS media queries get involved, and why the tooling has to generate more than one file format per image.
The README frames the goal as doing justice to users on all different browsers and devices, and calls the tedious, tricky things something that should be automated. The gem's own summary is that it is your responsive images minion, give it simple instructions and it'll handle the rest.
The claim on the features list is a little blunter: make Lighthouse happy.
What the gem generates
The features list is short, and the three items are the whole workflow.
First, generate piles of cropped, resized, and converted image files. Second, generate corresponding markup in several different formats. Third, configure it easily, or not at all.
That third point is the one that makes the gem usable in an existing site. The README says it offers extensive configuration while requiring none, and the promise in the introduction is that it solves both the art direction and resolution switching problems with a little YAML configuration and a simple template tag.
So there are two levels of use. A site that just wants responsive images adds the tag and points it at an image, and gets sensible output. A site that needs art direction describes the crops and the breakpoints in YAML and gets markup that switches images rather than just scaling them.
The outputs are the reason the gem is more than a build script. The underlying work is a pile of derived image files, and each one has to be produced in every format the site wants to serve, which with WebP and AVIF means the same source image becomes a matrix of files. Doing that by hand is the chore the gem takes over, and the markup has to stay in step with the files, which is the part that is genuinely tedious.
The formats themselves are handled by the image backend, and the 2.0 changelog records the addition of format_quality default settings for webp, avif and jp2, plus image-format-specific write options.
The libvips switch and what it changed
Version 2.0 is the release that reshaped the gem, and its changelog entry is the most useful document in the repository for anyone upgrading.
The headline is a switch from ImageMagick to libvips, with three consequences spelled out. It is much faster. It will still attempt to use imagemagick if libvips cannot handle a particular image format. And it eliminates the ImageMagick v7 on Ubuntu pain the maintainer says they had been dealing with for so long.
The cropping model changed with the backend, and that is the part that breaks existing configuration. Cropping now uses the libvips smartcrop function, which does some magic to keep the most useful part of the image. Geometry is renamed to crop, and reduced to simple aspect ratios only, in the form width:height. Gravity is gone, replaced by keep, which is translated to a libvips interestingness setting.
The other requirement changes in the same release are Ruby >= 2.6 with Ruby 3.0 support, and Jekyll >= 4.0.
There is a long history of fixes around the backend selection, and they show the shape of the problem. 2.0.1 selects imagemagick deliberately when appropriate rather than rescuing all vips errors and trying again, which stops JPT from suppressing useful vips errors. 2.0.3 and 2.0.4 improve backend format support detection. 2.0.2 stops passing a quality argument when generating PNG files, because it only works on newer versions of vips and broke builds on older ones, including when deploying to netlify, and because the README notes it is not remarkably useful in the first place.
The 2.1.x line continues that thread. 2.1.0 checks whether the vips CLI is installed before trying to use it, and updates the minimum required mocha version to maintain compatibility with minitest. 2.1.1 does not provide a Q setting for PPM images and fixes alpha premultiplication. 2.1.2 removes an overly specific version spec for ruby-vips. And 2.1.3 decides whether to call magick or convert more intelligently, which adds Windows support without breaking Jekyll Picture Tag on Ubuntu or other distros that only ship an ancient version of ImageMagick.
Installing the gem, and the build-time dependencies
The README is a pointer rather than a manual, and the installation steps live in the documentation site at rbuchberger.github.io/jekyll_picture_tag, with a changelog at the dev releases page.
What the repository itself shows is the packaging. There is a jekyll_picture_tag.gemspec, a Gemfile, a Rakefile, a lib/ directory for the code, a test/ directory, docs/ for the documentation sources, a .rubocop.yml for the linter and a mise.toml for tool versions, plus a .envrc for direnv. The presence of both a gemspec and a Rakefile alongside a mise.toml and a .envrc tells you this is a gem developed with a modern Ruby toolchain, with a test suite and a linter configured.
The dependency that matters is the image backend. Because the work happens at build time, the machine that runs jekyll build needs libvips, or ImageMagick for the formats libvips cannot handle. That is a deployment consideration rather than a development one, and it is worth checking against whatever builds the site, since a static site build on a managed host is where a missing native library shows up.
The 2.1.0 entry about checking whether the vips CLI is installed before trying to use it is a small example of the same theme. A missing binary should produce a clear message rather than a confusing failure, and the maintainer has been tightening that behaviour across releases.
The AI contribution policy, and the version without it
The README carries an AI Policy section, and it is stricter than most and more specific than most, so it is worth reading in full.
The use of LLM powered coding tools is permitted, so long as four conditions hold. Any commits with any AI generated code have a trailer Assisted-by: <model>. All changes are read completely and reviewed thoroughly by a knowledgable human before merging to master, with the note that this has always been the case, but it is especially true for AI-generated code. Pull request authors have done the same before submitting. And any GitHub interaction, whether an Issue, a pull request or a comment, that is written or posted using an LLM must clearly state this fact at the beginning, in bold, using a complete sentence, describing the nature of the LLM's involvement and the amount of human effort spent.
The README gives three worked examples of that disclosure, and the middle one is about translation rather than code. A comment can be written by AI after a 40 word prompt, 14 questions and answers, and one round of review and feedback. A translation can be produced by AI from Polish, more or less directly. An edit can be made by AI for grammar and clarity, based on an input of approximately similar size.
Then the escape hatch, and it is a concrete one. If you prefer to avoid running AI-generated code, the last version without it is 2.1.3. You will be stuck on Ruby 3, but other than that it works just fine.
So the project gives its users a way to opt out of the whole toolchain at a known version, which is a courtesy that more projects could offer. The condition attached to it is the one that matters: the version without AI contributions is the current release, and the policy is about how contributions are made, not about whether the code is any good.
Where jekyll_picture_tag fits, and where it stops
The comparison worth making is with the other two ways to get responsive images into a Jekyll site.
The first is doing it by hand with the picture element and a srcset. Jekyll has built in image processing, so a site can generate resized files and reference them, and for a handful of images that is entirely reasonable. The cost of doing it by hand is that the markup and the file list have to be kept in step by hand, and the number of formats multiplies the work.
The second is a JavaScript library that resizes in the browser or at runtime, or a service such as a CDN image transformation layer. Those move the work off the build machine and give you per-request formats, at the cost of a runtime dependency and, in the browser case, a flash of unstyled or low resolution image.
jekyll_picture_tag sits in the build-time corner and does the whole matrix: the crops, the resolutions, the formats and the markup. Its advantage is that the output is static and the markup matches the files by construction. Its cost is that the build machine needs the native image libraries, and the 2.0 changelog shows the author paying that cost twice, first with the ImageMagick v7 problem on Ubuntu and then with the format support detection across libvips versions.
The limits are specific. It is a Jekyll plugin, so it does nothing for a site on another generator. It is a build-time image pipeline, so a large media library makes builds slower and the generated files have to live somewhere. And the 2.0 change to cropping is a breaking change for anyone who had written crop configuration, because geometry became crop with aspect ratios only, and gravity was replaced by keep.
For a site that has been putting a full size image on every page, it is a real improvement with a bounded amount of configuration. The 2.1.3 release is the one to read the changelog for before upgrading, since it is both the current version and the last one without AI-generated contributions.
Editorial conclusion
jekyll_picture_tag suits a Jekyll site that needs proper responsive images without hand writing picture elements, srcset lists and CSS for every breakpoint, since the gem generates the image files and the markup together and supports art direction where different crops are wanted per breakpoint. It is the wrong tool if your site is not Jekyll, and it is the wrong tool if you cannot run libvips or ImageMagick on the build machine, because the image work happens at build time. Before adopting it, read the 2.0 migration guide, because the backend switch from ImageMagick to libvips changed the cropping options and dropped the markup_presets and media_presets configuration names in favour of presets and media_queries.
Frequently asked questions
What does jekyll_picture_tag do?
It automatically builds cropped, resized and reformatted images, generates the corresponding markup in several different formats, and resolves both the art direction and the resolution switching problem with a little YAML configuration and a simple template tag.
What changed in jekyll_picture_tag 2.0?
Version 2.0 switched from ImageMagick to libvips, which is much faster and eliminates the ImageMagick v7 problem on Ubuntu, while still falling back to ImageMagick for formats libvips cannot handle. Cropping moved to the libvips smartcrop function, geometry was renamed to crop and reduced to simple aspect ratios, gravity was replaced by keep, and it now requires Ruby 2.6 or newer and Jekyll 4.0 or newer.
Does jekyll_picture_tag require ImageMagick?
Not since version 2.0, which uses libvips as the backend and only attempts ImageMagick when libvips cannot handle a particular image format. Version 2.1.3 added smarter selection between magick and convert, which added Windows support without breaking the gem on distributions that ship an old ImageMagick.
Can I avoid AI-generated code in jekyll_picture_tag?
Yes. The README states that the last version without AI-generated code is 2.1.3, and that you will be stuck on Ruby 3 but otherwise it works fine. The project's policy allows LLM assisted contributions provided commits carry an Assisted-by trailer, changes are reviewed by a human, and any GitHub interaction written with an LLM says so at the start in bold.
Where is the jekyll_picture_tag documentation?
At rbuchberger.github.io/jekyll_picture_tag, with the changelog at the dev releases page on the same site. The README is a summary of the project and links to the site for installation, usage and the version notes, and there is a 2.0 migration guide at the users notes path.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rbuchberger-jekyll-picture-tag)Was this useful?