Krantho is in active development and not yet published to npm. Read what that means today.
esc

Search the documentation and product pages. Type “theme” to switch themes.

Features

Media on any store

Media files live where your site runs, and the choice is one configuration value.

Problem

Images and files need a home that fits the host. A local folder does not survive on serverless functions, and a hosted asset service is one more account and one more bill. Changing hosts should not mean changing how every image is stored and linked.

Approach

Media is two things, kept in two places. Metadata — name, alt text, tags, folder, crop, hotspot and dimensions — lives in your database, versioned like content. The file bytes live in a file store chosen by media.provider:

Storemedia.providerFits
Local disklocaldevelopment, a single server or container with a volume
Vercel Blobvercel-blobVercel
S3-compatibles3AWS, Cloudflare R2, MinIO, any S3 API
Google Cloud StoragegcsCloud Run, GKE, Compute Engine, any host with a key

Each store is its own package, so an app installs only the SDK it uses. Every file gets a new key that is never reused, so a file's URL can be cached for good; replacing an image writes a new key and updates the content that pointed at the old one.

In the admin, editors upload by drag and drop, organize files in folders, tag them, write alt text, and set a crop and a hotspot for images.

Proof

Media is configuration, not code. Choosing a store is one leaf of krantho.config.ts, or its environment variable:

.env
KRANTHO_MEDIA_PROVIDER=s3
KRANTHO_MEDIA_S3_BUCKET=site-media
KRANTHO_MEDIA_S3_REGION=eu-north-1

A missing setting stops startup with a message that names the setting and its variable.

krantho.config.ts
import { defineKranthoConfig } from '@krantho/config'

export default defineKranthoConfig({
  site: {
    domain: 'example.com',
    name: 'Example',
    language: 'en',
    baseUrl: 'https://example.com',
  },
  // local, vercel-blob, s3 or gcs. Each store has its own package, such as
  // @krantho/media-s3; leaving the provider unset turns media off.
  media: {
    provider: 's3',
    s3: { bucket: 'my-site-media', region: 'eu-north-1' },
  },
})

// Credentials stay in the environment. S3 and Google Cloud Storage can also
// use the host's own identity (an IAM role, a service account):
//   KRANTHO_MEDIA_S3_ACCESS_KEY_ID, KRANTHO_MEDIA_S3_SECRET_ACCESS_KEY
//   KRANTHO_MEDIA_VERCEL_BLOB_TOKEN, KRANTHO_MEDIA_GCS_CREDENTIALS

Limits

  • Media is off until media.provider is set.
  • Media needs SQLite or Postgres. The filesystem backend has no media.
  • Local disk only works where every instance shares one persistent disk. It does not fit serverless hosts.
  • S3 and Google Cloud Storage objects must be publicly readable, from the bucket itself or through a CDN in front of it.
  • On Express and Vite sites, an open issue corrupts binary uploads on their way through the Node adapter. Next.js and SvelteKit sites are not affected.