PAS7 Studio
Illustration einer Bun.js-, S3- und Sharp-Pipeline
Technologie27. Aug. 2026·3 Min. Lesezeit·Aktualisiert 27. Aug. 2026

Bun.js + S3 + Sharp: eine Pipeline für Upload und Bildoptimierung

So entsteht eine sichere Bild-Pipeline mit Bun.js, presigned S3-URLs, Sharp, WebP-Varianten und serverseitiger Validierung.

Full-Stack-EntwicklerMedia-Plattform-TeamsTeams mit Upload-APIs

Bun validiert die angeforderten Dateidaten und liefert eine kurzlebige presigned PUT-URL. Der Browser lädt direkt in S3-kompatiblen Storage. Ein Worker liest das Original, erstellt mit Sharp WebP- und Thumbnail-Varianten und veröffentlicht nur geprüfte Objekte.

Große Dateien laufen nicht durch den API-Prozess.
Der Browser erhält keine AWS-Zugangsdaten.
Sharp vereinheitlicht Format, Abmessungen und Qualität.
Xin

Architektur ohne Proxy für Dateibytes

Bun ist die Control Plane, der Object Storage die Data Plane.

01

Upload vorbereiten

Der Client sendet Dateiname, MIME-Type und Größe. Die API prüft die Allowlist und liefert Key und presigned URL.

02

Direkt hochladen

Der Browser führt PUT nach S3 aus. Der Bun-Prozess hält die Datei nicht im Arbeitsspeicher.

03

Verarbeiten

Ein Worker liest das Original und Sharp erstellt Thumbnail und WebP-Vorschau.

04

Veröffentlichen

In der Datenbank werden nur geprüfte Keys, Dimensionen, MIME-Type und Status gespeichert.

Die Datei geht direkt in den Storage; Bun verwaltet Zugriff und Metadaten statt große Bytes zu proxyen.

Screenshot des Abschnitts architecture

Schritt 1: SDK und Sharp installieren

01

Abhängigkeiten hinzufügen

BASH
bun add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner sharp

Sharp enthält native Komponenten. Prüfe die optionalen Abhängigkeiten für die Docker-Zielplattform.

02

Bucket setzen

ENV
S3_REGION=eu-central-1
S3_BUCKET=media
S3_ENDPOINT=https://s3.example.com
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...

S3_ENDPOINT funktioniert auch mit R2 und MinIO. Der Secret Key darf nie ins Frontend.

Schritt 2: presigned PUT-URL ausstellen

Halte die URL kurzlebig, verwende einen zufälligen Object Key und binde sie an den erwarteten Content-Type. Prüfe die tatsächliche Objektgröße nach dem Upload.

TS
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: Bun.env.S3_REGION!, endpoint: Bun.env.S3_ENDPOINT || undefined, forcePathStyle: Boolean(Bun.env.S3_ENDPOINT) });
const allowed = new Set(["image/jpeg", "image/png", "image/webp"]);
export async function createUploadUrl(contentType: string) {
  if (!allowed.has(contentType)) throw new Error("Unsupported image type");
  const key = `originals/${crypto.randomUUID()}`;
  const command = new PutObjectCommand({ Bucket: Bun.env.S3_BUCKET!, Key: key, ContentType: contentType, ServerSideEncryption: "AES256" });
  return { key, url: await getSignedUrl(s3, command, { expiresIn: 300 }) };
}

Schritt 3: Varianten mit Sharp erzeugen

Vertraue nicht auf die Dateiendung. Dekodiere das Bild serverseitig und lehne ungültige oder übergroße Dateien vor der Veröffentlichung ab.

TS
import sharp from "sharp";
export async function makeVariants(input: Buffer) {
  const image = sharp(input, { limitInputPixels: 40_000_000 });
  const metadata = await image.metadata();
  if (!metadata.width || !metadata.height) throw new Error("Invalid image");
  const thumbnail = await image.clone().rotate().resize({ width: 480, height: 480, fit: "cover" }).webp({ quality: 78 }).toBuffer();
  const preview = await image.clone().rotate().resize({ width: 1600, withoutEnlargement: true }).webp({ quality: 84 }).toBuffer();
  return { thumbnail, preview, width: metadata.width, height: metadata.height };
}

rotate() berücksichtigt die EXIF-Ausrichtung; withoutEnlargement vergrößert kleine Bilder nicht.

Upload vorbereiten und Status verfolgen

Setze eine Datei nicht schon bei der URL-Ausgabe auf ready. Lege zunächst einen Datensatz mit pending an und ändere ihn erst nach der Objektprüfung durch den Worker auf ready.

TS
import { Elysia, t } from "elysia";
import { createUploadUrl } from "../storage";
export const uploadRoutes = new Elysia({ prefix: "/uploads" }).post("/prepare", async ({ body, set }) => {
  const upload = await createUploadUrl(body.contentType);
  // upload.key und userId mit status=pending speichern.
  set.status = 201;
  return { ...upload, status: "pending" };
}, { body: t.Object({ contentType: t.Union([t.Literal("image/jpeg"), t.Literal("image/png"), t.Literal("image/webp")]) }) });

Sicherheit und Kostenkontrolle

Upload-Endpunkte brauchen Limits auf jeder Stufe.

Größe begrenzen

Payloads begrenzen und die tatsächliche Objektgröße nach PUT prüfen.

Keys serverseitig erzeugen

UUIDs und User-/Projekt-Namespace statt beliebiger Client-Keys verwenden.

Scannen oder moderieren

Bei öffentlichen Inhalten Antivirus oder Moderation vor ready einbauen.

Lifecycle-Regeln verwenden

Abgebrochene Uploads und temporäre Originals automatisch löschen.

Schwere Arbeit auslagern

Sharp in einem Worker ausführen, damit die Upload-API responsiv bleibt.

Die Bild-Pipeline testen

Teste das dekodierte Ergebnis, nicht nur den HTTP-Status. So werden Qualitätsregressionen und kaputte native Dependencies nach einem Docker-Update sichtbar.

TS
import { expect, test } from "bun:test";
import sharp from "sharp";
import { makeVariants } from "./images";
test("erstellt ein begrenztes WebP-Thumbnail", async () => {
  const input = await sharp({ create: { width: 1200, height: 800, channels: 3, background: "#f97316" } }).png().toBuffer();
  const { thumbnail } = await makeVariants(input);
  const meta = await sharp(thumbnail).metadata();
  expect(meta.format).toBe("webp"); expect(meta.width).toBe(480); expect(meta.height).toBe(480);
});

Starte bun test --coverage; verwende MinIO oder einen separaten Test-Bucket für Storage-Integrationstests.

FAQ

FAQ

Funktioniert Sharp mit Bun?

Ja, aber Sharp hat native Dependencies. Installiere sie für die Zielplattform und führe einen Smoke-Test im Production-Docker-Image aus.

Sollten Dateien durch Bun laufen?

Bei großen Dateien besser nicht. Verwende eine presigned URL und lade direkt in S3-kompatiblen Storage.

Geprüft: 27. Aug. 2026Gilt für: Bun 1.3+Gilt für: AWS SDK v3Gilt für: Sharp 0.34+Gilt für: Amazon S3 oder S3-kompatibler StorageGetestet mit: Bun runtimeGetestet mit: @aws-sdk/client-s3Getestet mit: @aws-sdk/s3-request-presignerGetestet mit: Sharp

Fazit

Beschreiben Sie die Aufgabe — die ersten 15 Minuten der Beratung sind kostenlos.

Verwandte Artikel

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support
ai-assistants

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support

Praktischer Leitfaden zu Kosten fuer AI Assistants: RAG, Knowledge Base, Channels, Tool Use, Guardrails, Evaluations, Monitoring und Support.

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet
blogs

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet

Eine praxisnahe Analyse zur Nutzung von KI fur Landingpages: v0, Webflow AI, Builder.io, Framer-ahnliche Builder, UX-Generierung, Copy, SEO, Personalisierung, A/B-Tests, Template-Risiken, Accessibility, Security und technischer Schuldenaufbau.

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents
growth

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents

Suche verschiebt sich von Klicks zu Antworten. Bots und AI-Agents crawlen, zitieren, empfehlen — und kaufen zunehmend. Erfahren Sie, was AI SEO / GEO bedeutet, warum klassisches SEO nicht mehr reicht und wie PAS7 Studio Marken im agentischen Web sichtbar macht.

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde
blogs

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde

Eine Analyse zu Apple M5 Pro und M5 Max im März 2026. Wir zeigen, warum diese Chips als die stärksten professionellen Laptop-SoCs von Apple gelten können, wie sie sich gegen M4 Pro, M4 Max, M1 Pro, M1 Max schlagen und was der Vergleich mit aktuellen Intel- und AMD-Chips zeigt.

Professionelle Entwicklung für Ihr Geschäft

Wir erstellen moderne Web-Lösungen und Bots für Unternehmen. Erfahren Sie, wie wir Ihnen helfen können, Ihre Ziele zu erreichen.