Skip to main content
Konifer

Self-hosted image infrastructure that fits your API.

Konifer stores original images, generates and caches transformed variants, and returns content, links, redirects, downloads, or metadata from URLs that follow your application's domain model.

# Store where the asset belongs
POST /assets/users/123/profile-picture

# Fetch a transformed image
GET  /assets/users/123/profile-picture/-/content?w=256&format=webp

# Fetch a transformed image using a defined transformation
GET  /assets/users/123/profile-picture/-/content?profile=thumbnail

# Ask for metadata, links, or redirects instead
GET  /assets/users/123/profile-picture/-/metadata
Your appKonifer APIObject storeCDN

Why teams use it

Konifer is for products that want Cloudinary- or Imgix-style capabilities while keeping control over storage, routing, processing, and delivery behavior.

Application-shaped asset paths

Use URLs that match your product model, such as users, organizations, listings, posts, and documents. Konifer does not force your app to persist opaque media IDs just to render an asset later.

One API for storage and delivery

Store originals, attach metadata, request the newest asset at a path, address a specific entry, or fetch generated variants through the same HTTP surface.

Transformations without vendor lock-in

Resize, crop, rotate, blur, pad, strip metadata, manage color space, and convert formats on demand or through named variant profiles.

CDN-aware by design

Serve bytes directly, return object-store links, issue redirects, use Cache-Control and ETags, and protect public transformation URLs with HMAC signing.

An API philosophy built around integration

Most media services become a separate source of truth. Konifer is designed so your existing application state can construct useful asset URLs directly.

Query selectors live behind the /-/ separator, keeping product paths separate from delivery instructions.

Ordering
/-/newMost recently created/-/modifiedMost recently modified/-/entry/42Absolute asset reference
Return format
/-/content/-/link/-/redirect/-/download/-/metadata

Treat a path like a domain primitive

Because new is the default ordering selector, fetching a path behaves like reading the top of a stack. Post a new asset to the same path and your app can hot swap an avatar, publish a new hero image, or keep simple version history without changing the URL it already knows.

Explore query selectors
POST /assets/products/sku-123/heroPOST /assets/products/sku-123/heroGET  /assets/products/sku-123/heroreturns the newest asset by default

Transform once, cache for the next request

Request image variants on demand or define named profiles for common outputs. Generated variants are stored and reused, so expensive work does not repeat for every viewer.

JPEGPNGWebPAVIFJPEG XLHEICGIF
w=1200h=630fit=cropblur=10format=webpq=82r=auto

Path Configuration is where the flexibility compounds

Configure behavior by path pattern, then let inheritance do the work. Public avatars, private user content, CMS images, and generated media can share one service while using different storage buckets, validation rules, eager variants, preprocessing, redirect strategies, caching, and LQIP behavior.

Read Path Configuration
paths = [
  {
    path = "/public/avatars/**"
    eager-variants = [ small, medium, large ]
    return-format.redirect.strategy = template
    cache-control.max-age = 31536000
  },
  {
    path = "/users/*/profile-picture"
    bucket = "profile-pictures"
    allowed-content-types = [ "image/jpeg" ]
  }
]

Built as the beginning of a media engine

Konifer is image-focused today. The longer-term direction is broader: a self-hosted engine for media assets such as PDFs, audio, text, and eventually video, with the same path-based integration model.

Run Konifer locally