How the Instatic Media Workspace Manages Uploads and Image Variants

Instatic’s media workspace implements a three-stage upload pipeline that isolates byte-transfer from the QuickJS sandbox, stores files via pluggable storage adapters, and automatically generates optimized WebP image variants for responsive delivery.

The Instatic media workspace provides a complete asset management system that handles everything from file ingestion to responsive image delivery. As implemented in the CoreBunch/Instatic repository, this architecture separates upload orchestration from byte-stream execution while supporting multiple storage backends through a plugin-based adapter system.

Three-Stage Upload Pipeline Architecture

Upload Orchestration and Validation

When a user drops a file onto the Media canvas or submits via the upload queue, the UI calls POST /admin/api/cms/media. The handler in server/handlers/cms/mediaUpload.ts validates the file through size checks and MIME sniffing before forwarding to mediaUploadDispatch.ts.

This dispatch layer selects the elected storage adapter based on the asset's role—whether original, variant, or avatar—and invokes the adapter's beginWrite method to generate a MediaStorageUploadPlan containing signed URLs or local-disk sentinels.

Byte-Stream Execution Outside the Sandbox

The host executes mediaUploadExecutor.ts, which iterates over each step of the upload plan while streaming bytes outside the QuickJS sandbox.

For the built-in local-disk adapter, the executor detects the sentinel constant LOCAL_DISK_STEP_METHOD ('LOCAL') and writes directly using fs.writeFile. Remote adapters trigger 'PUT' or 'POST' steps, where the executor uses Bun's native fetch to transmit slices with appropriate Content-Length headers and signed request signatures.

Finalization and Event Broadcasting

After all steps complete successfully, the adapter's finalizeWrite returns a public URL—either /uploads/<path> for local storage or a signed read URL for external providers.

The handler persists the new row to the media_assets table via server/repositories/media.ts and emits a mediaAssetCreated event through mediaAssetEvents.ts, enabling real-time refresh across all open Media windows.

Automatic Image Variant Generation

WebP Ladder and Blurhash Computation

Once the original asset exists in the database, the host invokes the image-variant worker (server/handlers/cms/imageVariantWorker.ts). This worker utilizes the sharp library to probe the source image, compute a blurhash for placeholder display, and generate a responsive ladder of WebP files at predefined widths ranging from 64 px up to the intrinsic image width.

Variant Metadata Storage

Variant metadata—including width, height, format, path, sizeBytes, storagePath, and storageAdapterId—is serialized into the JSON column variants_json of the media_assets table.

The mapping logic in server/repositories/mediaAssetMapping.ts parses this column to produce the RenderResolvedMedia shape used throughout the application.

Responsive Rendering and Storage Abstraction

Building Srcset and Selecting Optimal Variants

Both the admin UI and public publisher consume the same RenderResolvedMedia interface. Helper functions in src/modules/base/utils/mediaAttrs.ts construct responsive image attributes: buildMediaSrcset assembles a srcset string from the variant ladder, while pickMediaVariantUrl selects the smallest variant meeting or exceeding the requested width.

The publisher's mediaPresentation.ts streams these URLs to clients, while the admin canvas renders previews using identical helpers.

Pluggable Storage Adapter System

The mediaStorageRegistry.ts maintains a registry of storage adapters initialized at boot, including the built-in local-disk adapter configured via configureLocalDisk.

Plugins can register additional adapters through the SDK's api.cms.media.registerStorageAdapter method, provided they hold the media.storage.adapter permission. Each adapter declares a servingMode—either public-url for direct browser access or non-public-url requiring signed redirects through /_instatic/media/<adapterId>/<storagePath>.

Implementation Examples

Creating an upload plan through the adapter interface:

// Adapter-side plan creation
await adapter.beginWrite({
  suggestedStoragePath: 'my-image-abc123.webp',
  role: 'original',
});

Executing the upload plan on the host:

// Host-side execution outside the sandbox
import { executeUploadPlan } from '@core/mediaUploadExecutor';
await executeUploadPlan(plan, fileBytes);

Selecting responsive variants in a React component:

// Responsive image selection utilities
import { pickMediaVariantUrl, buildMediaSrcset } from '@modules/base/utils/mediaAttrs';

const src = pickMediaVariantUrl(resolvedMedia, 1280);
const srcset = buildMediaSrcset(resolvedMedia);

Registering a custom storage adapter via the plugin SDK:

// Plugin SDK registration for external storage
api.cms.media.registerStorageAdapter({
  id: 'myS3',
  label: 'S3',
  roles: ['original', 'variant'],
  servingMode: 'non-public-url',
  // ...implement beginWrite, finalizeWrite, abortWrite...
});

Summary

  • The upload pipeline in mediaUpload.ts and mediaUploadDispatch.ts validates files and creates signed upload plans through pluggable adapters.
  • mediaUploadExecutor.ts streams bytes outside the QuickJS sandbox using local file system writes or remote HTTP requests.
  • Original assets persist via server/repositories/media.ts, triggering mediaAssetCreated events for real-time UI updates.
  • The imageVariantWorker.ts generates WebP ladders and blurhashes, storing metadata in the variants_json column.
  • mediaAttrs.ts provides buildMediaSrcset and pickMediaVariantUrl helpers for responsive image rendering across admin and public contexts.

Frequently Asked Questions

How does Instatic handle large file uploads without blocking the QuickJS sandbox?

Instatic isolates byte-transfer operations in mediaUploadExecutor.ts, which runs on the host outside the sandbox. The executor processes MediaStorageUploadPlan steps using either fs.writeFile for local storage or Bun's native fetch for remote adapters, ensuring the JavaScript sandbox remains unblocked during large file transfers.

What image formats does the variant generator produce?

The imageVariantWorker.ts automatically generates WebP variants at predefined widths (64 px, 320 px, and up to the intrinsic width). It also computes a blurhash string for low-quality image placeholders, storing all variant metadata in the variants_json column of the media_assets table.

Can I use external storage providers like S3 with Instatic?

Yes. The mediaStorageRegistry.ts supports custom adapters registered via the plugin SDK's api.cms.media.registerStorageAdapter method. Adapters implement beginWrite, finalizeWrite, and abortWrite methods, and can specify servingMode: 'non-public-url' to route requests through /_instatic/media/<adapterId>/<storagePath> with signed redirects.

How does the media workspace select the right image size for different devices?

The pickMediaVariantUrl function in src/modules/base/utils/mediaAttrs.ts selects the smallest variant with a width greater than or equal to the requested display width. For comprehensive responsive support, buildMediaSrcset constructs a complete srcset attribute from the variant ladder stored in variants_json, allowing browsers to choose optimal resolutions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →