# MiniMagick: a Ruby wrapper that shells out to ImageMagick instead of loading it

> MiniMagick wraps the ImageMagick command line so Ruby processes stay small, and it hands you every option the CLI has. The trade-off is that it depends on a binary being present and correct.

**minimagick/minimagick** — mini replacement for RMagick

- Repository: https://github.com/minimagick/minimagick
- Website: https://rubydoc.info/gems/mini_magick
- Stars: 2,864 · Forks: 350
- Language: Ruby
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/minimagick-minimagick

## The memory ceiling that MiniMagick was written to get under

The README states the origin story plainly: the author was using RMagick and liking it, but a simple script would use over 100MB of RAM. That was fine locally and fatal on a hosting server with a 100MB process limit, where the Ruby apps would crash. MiniMagick's answer is to not link against ImageMagick at all. It spawns the command line program, and the README concedes that the spawned process takes up memory as well, but much less than RMagick inside the Ruby process.

That framing tells you who this is for. It is for Rails and Sinatra apps on constrained containers, background workers that process uploads, and anyone who has already been bitten by a memory limit rather than by a missing feature. It is not a reimplementation of image processing. The README says MiniMagick gives you access to all the command line options ImageMagick has, which means the feature set is ImageMagick's feature set, reached through Ruby method calls and a builder object.

## How MiniMagick talks to the magick binary

The core mechanism is a temporary file plus a subprocess. `MiniMagick::Image.open` makes a copy of the image, and further methods modify that copy; the original stays untouched. The README's example shows the copy living under a temp directory with a name like `/var/folders/.../magick20140921-75881-1yho3zc.jpg`. Because that copy is temporary and garbage collected when you lose the reference, writing the result out is not optional. If you skip `#write`, the work is thrown away.

`MiniMagick::Image.new` is the other mode. It points at the file you passed in, so `image.path` returns `input.jpg` itself and mutations apply to it, which is why the README notes you do not call `#write` in that case.

The efficiency question is the interesting one. Calling `#resize` and then `#rotate` runs the command twice. `combine_options` exists to fix that: it takes multiple options and builds one single command, and `MiniMagick::Image.new` accepts a block that is used as `combine_options`. The yielded object is a `MiniMagick::Tool`. For a pipeline of three operations, that is the difference between three subprocess spawns and one.

Reading data back follows the same route. Attributes like `type`, `width`, `height`, `dimensions`, `size`, `colorspace`, `exif`, `resolution` and `signature` are exposed as methods, and `image["%[gamma]"]` reaches raw ImageMagick escape attributes. `image.data` returns the parsed output of `magick input.jpg json:`, a hash with format, mimeType, geometry, resolution, channelDepth, quality and a properties map containing EXIF and ICC keys. Pixels come back as a matrix of 3-element RGB arrays via `get_pixels`, and `get_image_from_pixels` goes the other way given pixels, a dimension pair, a map string and a depth.

## Installing MiniMagick and resizing your first image

The gem is not self-contained. The README's Requirements section says the ImageMagick command-line tool has to be installed, and gives `magick -version` as the check. That command prints a version line, a copyright line, a license URL, a Features line and a Delegates line listing the built-in codecs such as jpeg, png, tiff, webp and heic. Read the Delegates line before you assume a format works: a build without the delegate you need will fail at runtime, not at install time.

Add the gem to your Gemfile with the command the README shows:

```sh
$ bundle add mini_magick
```

Then a minimal resize, format conversion and write:

```rb
require "mini_magick"

image = MiniMagick::Image.open("input.jpg")
image.resize "100x100"
image.format "png"
image.write "output.png"
```

After this runs you should have `output.png` next to your script, and `image.path` should point at a temporary copy rather than at `input.jpg`. If you want several operations applied in a single ImageMagick invocation, use the builder form instead:

```rb
image.combine_options do |b|
  b.resize "250x200>"
  b.rotate "-90"
  b.flip
end
```

The block runs when it closes. `MiniMagick::Image.open` also accepts URLs, forwarding options to open-uri, so `MiniMagick::Image.open("http://example.com/image.jpg")` works and the README's example follows it with `image.contrast` and `image.write("from_internets.jpg")`.

## The binary is the dependency, and that is the failure mode

Everything MiniMagick does is delegated. Your code does not control which ImageMagick version runs, only which one happens to be on PATH, and the README's own version check shows a 7.x build with the `magick` entry point while older ImageMagick releases shipped `convert` and `mogrify` as separate commands. If your production image, your CI runner and a developer laptop disagree about which binary is installed, the same Ruby code can behave differently on each.

This also makes MiniMagick the wrong tool in two specific situations. First, if you cannot install system packages (some managed runtimes, some serverless environments), there is nothing for the wrapper to call. Second, if your image inputs come from untrusted users, you are passing them to a command line tool, and the README does not document any sanitization layer or sandboxing. MiniMagick's job is to build the argument list, not to police it. That is a property of the design, not a bug report, but it belongs in your threat model before you wire it to an upload form.

A third limit is subtler. Because results are files and subprocesses, there is no in-memory pipeline to compose. You get a path, you write a path. Code that wants to keep an image in memory and hand it to another library without touching disk is fighting the grain of this design.

## MiniMagick versus RMagick and image_processing

RMagick is the direct alternative and the one the README names. It binds to the ImageMagick libraries in-process, so you get an object model and no subprocess spawn per operation, at the cost of the memory profile the README describes: over 100MB for a simple script. If your constraint is memory, MiniMagick wins on the author's stated grounds. If your constraint is throughput on a machine with memory to spare, RMagick's in-process calls avoid the fork and exec overhead that MiniMagick pays on every operation. Neither is universally better; they optimize different resources.

image_processing sits at a different level. It is a higher-level layer that typically wraps MiniMagick underneath, aimed at common tasks like variants and thumbnails rather than at exposing raw command line options. Choosing it means choosing convenience over the direct option passthrough that MiniMagick's `combine_options` and `MiniMagick::Tool` give you. If you need an obscure ImageMagick flag, the higher-level layer has to expose it first.

CarrierWave is not a competitor but a common pairing, and it is worth noting that the uploader does not change the underlying constraint: whichever uploader you use, MiniMagick still needs the binary.

## Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-08-31, the same day as the v5.4.0 release. The two prior releases, v5.3.3 and v5.3.2, landed on 2026-08-06 and 2026-07-14, so the release cadence over that window is roughly monthly. The version numbering has moved into 5.x, and the CHANGELOG.md at the repository root is where the project records what changed between them; read it before a major bump rather than after.

The gem is MIT licensed, which in practice means you can use it in closed-source applications provided you keep the licence notice. That is a description of the licence text, not legal advice; if your organisation has a policy on bundled licences, route it through whoever normally handles that.

The real upgrade cost is not the gem. It is the ImageMagick binary underneath. Bumping `mini_magick` in your Gemfile does not change which ImageMagick your container runs, and a base image rebuild can change it without any Gemfile edit at all. Pinning the gem without pinning the binary gives you a false sense of stability. The README documents the version check command but does not document a supported ImageMagick version range, so there is no stated floor or ceiling to test against.

## Conclusion

Adopt MiniMagick when your Ruby process memory ceiling is the constraint and you are willing to install and pin the ImageMagick binary on every machine that runs the code. Do not adopt it for in-process pixel manipulation, for environments where you cannot control the system packages, or if you need RMagick's object model and its full drawing API. Before committing, verify three things on your own target: that `magick -version` reports a build with the delegates your formats need, that your image inputs are not attacker-controlled, and that the ImageMagick version on your CI machine matches the one in production, because MiniMagick passes your options through to whatever binary it finds.

## FAQ

### What is ImageMagick used for?

ImageMagick is the command line tool that MiniMagick wraps. The README says MiniMagick gives you access to all the command line options ImageMagick has, and its Requirements section says the ImageMagick command-line tool has to be installed for the gem to work.

### Who uses ImageMagick?

The README does not describe an ImageMagick user base. It describes MiniMagick's own audience indirectly: the author moved to it from RMagick because a simple script used over 100MB of RAM and Ruby apps crashed on a hosting server with a 100MB memory limit.

### What functions does ImageMagick have?

The README does not enumerate ImageMagick's functions; it points to the command line options page on imagemagick.org and says MiniMagick exposes all of them. The usage examples show resizing, format conversion, rotation, flipping, cropping and colorspace changes.

### What are some good alternatives to ImageMagick?

The README does not list alternatives to ImageMagick itself. It does compare MiniMagick with RMagick, naming the memory difference as the reason it exists, and mentions image_processing and CarrierWave only as related Ruby tooling.

## Sources

- [License: MIT](https://github.com/minimagick/minimagick/blob/master/LICENSE)
- [minimagick/minimagick on GitHub](https://github.com/minimagick/minimagick)
- [Project website](https://rubydoc.info/gems/mini_magick)
- [README](https://github.com/minimagick/minimagick/blob/master/README.md)
- [Releases](https://github.com/minimagick/minimagick/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/minimagick-minimagick
