Setup
Install `@dimah-s3/server`, configure S3, and mount the route.
Install
npm i @dimah-s3/server @aws-sdk/client-s3S3 client
AWS_REGION="us-east-1"
AWS_ACCESS_KEY_ID="your-access-key-id"
AWS_SECRET_ACCESS_KEY="your-secret-access-key"
AWS_S3_BUCKET="your-bucket-name"import { S3Client } from "@aws-sdk/client-s3";
export const s3Client = new S3Client({
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
export const defaultBucket = process.env.AWS_S3_BUCKET!;Provider quirks (POST vs PUT, ACL, path-style): Providers.
Config
Enable only what you need. Start minimal for upload-first apps.
import { dimahS3 } from "@dimah-s3/server";
import { s3Client, defaultBucket } from "@/lib/s3-client";
export const s3 = dimahS3({
s3: s3Client,
defaultBucket,
// R2: { enabled: true, method: "PUT" }
upload: { enabled: true },
download: { enabled: false },
delete: { enabled: false },
multipart: { enabled: false },
});Hook reference: Guard, Upload, Download, Delete, Multipart.
Prop
Type
Route handler
Mount at /api/s3 by default. Full examples for every supported framework: Adapters.
import { toNextJsHandler } from "@dimah-s3/server/next";
import { s3 } from "@/lib/s3";
export const { GET, POST, DELETE } = toNextJsHandler(s3);Also available: @dimah-s3/server/fastify, @dimah-s3/server/elysia, @dimah-s3/server/svelte-kit, @dimah-s3/server/node.
Custom base path — set basePath on dimahS3({ basePath }) and pass the same value to createS3Client({ basePath }) on the client.
Server api
Call the same protocol from Server Actions or RSC without HTTP. Pass headers so guards / db scope still see the request context.
"use server";
import { headers } from "next/headers";
import { s3 } from "@/lib/s3";
export async function getDownloadUrl(key: string) {
return s3.api.download(key, {
headers: await headers(),
});
}s3.api implements the same S3Api shape as the browser client (upload, confirm, download, delete, multipart). Errors throw DimahS3Error with a status field.
Client
On the frontend, use createS3Client from @dimah-s3/react (recommended) or @dimah-s3/core (fetch-only):
"use client";
import { createS3Client } from "@dimah-s3/react";
export const { api, S3Provider, useApi } = createS3Client();
export function S3ClientProvider({ children }: { children: React.ReactNode }) {
return <S3Provider>{children}</S3Provider>;
}Same basePath as the server when customized: createS3Client({ basePath: "/api/your-path" }).