Assets
Images, video and files, taken care of.
Upload once, in the editor, through the API or from an agent. Images take their size, crop and format from the URL, video and audio play in the browser, and files download from links that keep working.

Images
Images by URL. No pipeline.
Every image you upload gets a URL on a CDN. Write the size, crop and format into it, and your framework's image component does the rest.
// image-loader.ts export { nextImageLoader as default } from "@nohead/sdk/images" // next.config.ts export default { images: { loader: "custom", loaderFile: "./image-loader.ts", }, } // A page: a srcset of renditions, made on first request <Image src={cover.image_url} width={1200} height={630} alt={cover.alt} />
// astro.config.mjs export default defineConfig({ image: { service: { entrypoint: "@nohead/sdk/astro/image-service" }, }, }) // A page: Astro never fetches the image <Image src={cover.image_url} width={1200} height={630} alt={cover.alt} />
// providers/nohead.ts export { nuxtImageProvider as default } from "@nohead/sdk/images" // nuxt.config.ts export default defineNuxtConfig({ image: { provider: "nohead", providers: { nohead: { provider: "~/providers/nohead.ts" }, }, }, }) // A page <NuxtImg :src="cover.image_url" width="1200" height="630" :alt="cover.alt" />
import { imageUrl } from "@nohead/sdk/images" const url = imageUrl(cover, { width: 1200, height: 630, fit: "cover", format: "webp", }) // …/rs:fill:1200:630/plain/<project>/<asset>@webp
Smart crop, or your focal point
A crop keeps the most interesting part of an image, found for you, or the point you give it, so one photo works as a wide card and a square avatar alike.
AVIF, WebP and the rest, in the URL
Size, fit, format, quality, pixel density, blur and sharpen are imgproxy's options, written into the image's URL. Framework image components write them for you, and anything else can too.
Stored once, served close by
Files are stored once and served from a CDN, close to each visitor. A rendition is made the first time it's asked for and cached for a year; purge an asset, and its copies stop answering within a minute or so.
Never the original
Image URLs serve renditions only, never the file as stored and never its metadata, so a photo's location doesn't travel with it. The original downloads from its own URL.
Not metered
Image loads aren't API requests, and there are no per-rendition fees. Each visitor's address is rate limited, generously enough for pages full of images.
Video, audio and files
The rest of your files. Same CDN.
A product demo, a podcast episode, a price list as a PDF: each has a URL that plays it or downloads it, ready for a plain HTML tag.
// Video and audio play from the CDN, and players can seek <video src={clip.media_url} controls preload="metadata" playsInline /> <audio src={episode.media_url} controls /> // Every file downloads as uploaded, under its filename <a href={brochure.file_url}>Download {brochure.filename}</a>
- Plays in the browser, with seeking: MP4 and WebM video, MP3, AAC and WAV audio
- Downloads as uploaded, byte for byte, under the file's own name, whatever its type
- URLs that don't expire, cached at the edge for a year, so links and embeds keep working
- Gone when you say so: a purge clears a file from the CDN within a minute or so
Library
One library, wherever you work.

Your team uploads in the editor, your build and your agents through the API, the CLI or an SDK. Everyone sees the same files.
Alt text. Edited beside a preview, and used wherever the image appears.
Where it's used. The records that use a file, listed before anyone deletes it.
Found fast. Search by name or alt text, and filter by kind.
Dimensions. Read on upload, for layouts that don't jump.
Safe to upload.
Safe to serve.
Checked before it's kept. Every upload's size, type and contents are verified where it landed; a file that claims to be an image or a video and isn't is discarded.
Never a web page. Files are served from their own hosts, as downloads or as video and audio: nothing uploaded ever opens as a page on your domain or ours.
Deleted isn't gone. Deleted assets keep working and can be restored for 30 days. Purge one to free its storage at once.
Straight to storage. Uploads go directly from the browser, the CLI or an SDK to storage, not through the API, so large files don't wait on it.
@nohead/sdk has loaders for the image components of Next.js, Astro and Nuxt. Image loads aren't API requests, and there are no per-rendition fees. Other files are served as they are, from a URL that downloads them under their filename, and video and audio play in the browser. The images and files guide has the options.Upload a file, then change its URL.
Create a project, drop in an image and write a width into its URL. That's the whole image pipeline.