Openinary is an open-source, self-hosted media processing platform that includes:
- on-the-fly transformations for images and videos via URL
- built-in S3-compatible storage with automatic caching
- smart optimization with WebP, AVIF, and modern codecs
- simple REST API with URL-based transformations
- convenient admin dashboard for asset management
For documentation and more examples, please visit https://docs.openinary.dev.
Warning
Please keep in mind that Openinary is still under active development and therefore full backward compatibility is not guaranteed before reaching v1.0.0.
Important
PostgreSQL is now required. SQLite support has been removed. Configure the
database with DATABASE_URL; there is no migration tool from SQLite data —
deploy fresh on PostgreSQL. This is pre-1.0, per our backward-compatibility policy.
Make sure to have Docker 20.x+ and Node.js 20+ installed and running.
npx create-openinaryFollow the prompts to choose full stack vs. API-only and, optionally, S3-compatible storage. It scaffolds a project, writes a docker-compose.yml and .env, and starts the containers. Once it finishes, your Openinary instance is running at http://localhost:3000.
To get the full CLI suite (start, stop, upgrade, ...), install it globally:
npm i -g create-openinary- Open http://localhost:3000, you'll be redirected to
/setup - Create your admin account
- Click on your profile in the bottom left navigation, then go to 'API Keys' to generate your first API key
# Simple resize
GET /t/w_800,h_600/image.jpg
# Smart cropping with face detection
GET /t/w_400,h_400,c_fill,g_face/portrait.jpg
# Format conversion + optimization
GET /t/w_1200,h_800,f_avif,q_80/photo.jpg
# Aspect ratio with automatic detection
GET /t/ar_16:9,g_auto,w_1920,h_1080/banner.jpg# Thumbnail with resize
GET /t/w_800,h_450,so_5,f_avif/video.mp4
# Web optimized compression
GET /t/w_1280,h_720,q_75/video.mp4
# Extract a clip (from 10s to 30s)
GET /t/so_10,eo_30/interview.mp4
# Lightweight preview (low quality, small size)
GET /t/w_480,h_270,q_50/demo.mp4
# Format conversion with resize
GET /t/w_1920,h_1080,f_mp4/video.movOpeninary supports any S3-compatible storage. Configure via environment variables in apps/api/.env:
STORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=your_aws_access_key
STORAGE_SECRET_ACCESS_KEY=your_aws_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_PUBLIC_URL=https://your-bucket-name.s3.us-east-1.amazonaws.comSTORAGE_REGION=auto
STORAGE_ACCESS_KEY_ID=your_r2_access_key
STORAGE_SECRET_ACCESS_KEY=your_r2_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
STORAGE_PUBLIC_URL=https://your-custom-domain.comSTORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=your_access_key
STORAGE_SECRET_ACCESS_KEY=your_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ENDPOINT=https://your-s3-compatible-endpoint.com
STORAGE_PUBLIC_URL=https://your-cdn-domain.comFull Documentation | Issues | Contact
This repository holds the self-hosted product and the managed Cloud service side by side, so a fix to the shared engine reaches both without a release in between.
apps/api apps/web apps/telemetry the self-hosted product
apps/cloud Openinary Cloud (server, web, admin)
apps/marketing apps/docs openinary.dev and its documentation
packages/ core, ui, cli, registry, shared
See Project Structure for the full tour.
Everything in this repository is AGPL-3.0 — see LICENSE — with two exceptions:
apps/cloud/is the managed Cloud service. It is source-available, not open source: read it, audit it, contribute to it, but running it needs a written agreement. See apps/cloud/LICENSE.apps/marketing/(the website) is MIT.
Self-hosting Openinary needs nothing from apps/cloud/. The AGPL parts are the
whole product.