Just released v0.11.0 of <Konifer>, an image-manag...
# server
d
Just released v0.11.0 of Konifer, an image-management platform built with Ktor and libvips, a demand-driven, streaming image processing library. I’ve seen many image processors and proxies built in Go. With Java’s Foreign Function and Memory API, Kotlin's structured concurrency, and the broader JVM ecosystem, I wanted to explore a cross-cutting problem I’ve encountered throughout my career: unified image management. Konifer is built around two ideas: 1. Images often belong to a domain resource, but most systems make applications manage a separate image identifier. A user’s profile picture, a product’s hero image, or a loyalty card’s artwork can instead have a stable, meaningful path:
/assets/users/123/profile-picture
. Query selectors then determine how it is returned:
/-/content
,
/-/redirect
,
/-/info
, and so on. 2. Images in different parts of a domain need different policies. With Konifer’s Path Configuration, transformation, lifecycle, caching, and moderation policies are bound directly to asset paths. Profile pictures can follow different rules from blog or product images. For example, this configuration limits profile-picture uploads to 10 megapixels, strips EXIF metadata, applies EXIF-based auto-rotation, and eagerly generates a thumbnail:
Copy code
variant-profiles {
  thumbnail {
    w = 256
    h = 256
    fit = fit # Preserve aspect ratio within a 256x256 box
    format = webp
  }
}

paths {
  "/users/*/profile-picture" {
    limits {
      max-pixels = 10MP
    }
    transform {
      preprocessing {
        enabled = true
        r = auto
        strip = [ exif ]
      }
      eager-variants = [ thumbnail ]
    }
  }
}
Other highlights include: • On-demand and eager variant generation with retention policies • Upload Rules that accept, reject, or modify uploads using prompt ensembles powered by Google’s SigLIP2 • A Rule Evaluation API for testing Upload Rules or performing standalone zero-shot image classification • JPEG, PNG, WebP, AVIF, JPEG XL, HEIC, and GIF support, including animated WebP and GIF • ETag support and configurable
Cache-Control
behavior • Performance data published for each release, making changes in compute-heavy operations visible over time. Running this on AWS instances is high on my roadmap. As I approach my 1.0 release, I’d love feedback from other Kotlin server developers, particularly on the path-based model, configuration approach, and return formats.
🔥 1
Small correction: the example config is using configuration that will work against
main
, however, in version
0.11.0
, the
preprocessing
config would look like this:
Copy code
preprocessing {
  enabled = true
  image {
    r = auto
    strip = [ exif ]
  }
}
I will call out these breaking changes in my release notes when 1.0 is released. My documentation currently reflects what's in
v0.11.0