Quickstart
Minimal setup for Next.js with server and client hooks.
Install
npm i @dimah-s3/server @dimah-s3/react @dimah-s3/ui @aws-sdk/client-s3S3 client
S3_ENDPOINT="https://your-endpoint.example.com"
S3_REGION="auto"
S3_ACCESS_KEY_ID="your-access-key-id"
S3_SECRET_ACCESS_KEY="your-secret-access-key"
S3_DEFAULT_BUCKET="your-bucket-name"import { S3Client } from "@aws-sdk/client-s3";
export const s3Client = new S3Client({
region: process.env.S3_REGION,
endpoint: process.env.S3_ENDPOINT,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
},
});
export const defaultBucket = process.env.S3_DEFAULT_BUCKET!;Works with any S3-compatible provider. Setup may differ by provider — see Providers.
Server config and route
import { dimahS3 } from "@dimah-s3/server";
import { s3Client, defaultBucket } from "@/lib/s3-client";
export const s3 = dimahS3({
s3: s3Client,
defaultBucket,
upload: { enabled: true },
download: { enabled: false },
delete: { enabled: false },
multipart: { enabled: false },
});import { toNextJsHandler } from "@dimah-s3/server/next";
import { s3 } from "@/lib/s3";
export const { GET, POST, DELETE } = toNextJsHandler(s3);More frameworks (Fastify, Elysia, Node, Workers): Server adapters.
Upload-only is now live on /api/s3.
Client provider (standard)
"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>;
}Mount once near your app root — provider for hooks/UI, toaster for feedback (same pattern as the examples):
import { Toaster } from "@dimah-s3/ui";
import { S3ClientProvider } from "@/components/s3-provider";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<S3ClientProvider>{children}</S3ClientProvider>
<Toaster />
</body>
</html>
);
}Registry installs: import Toaster from @/components/ui/toast instead of @dimah-s3/ui.
UI setup
Theme variables and package install (toaster is already in the layout above):
npm i @dimah-s3/ui shadcn@import "shadcn/tailwind.css";
@import "@dimah-s3/ui/styles.css";
/* + shadcn theme variables */
shadcn theme variables must be in globals.css.
Mount the toaster once in your root layout:
import { Toaster } from "@dimah-s3/ui";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Toaster />
</body>
</html>
);
}Already using shadcn toast for your own messages? Mount both — rename one import (Toaster as DimahToaster). They are independent; your code keeps import { toast } from "@/components/ui/toast" and toast.add({ … }).
One upload button
"use client";
import { UploadButton } from "@dimah-s3/ui";
export default function Page() {
return (
<div>
<UploadButton
objectKey={(file) => `uploads/${Date.now()}-${file.name}`}
accept={["image/*", ".pdf"]}
maxFileSize={10 * 1024 * 1024}
label="Upload file"
/>
</div>
);
}At this point, selecting a file uploads directly to S3.
Need deeper setup details? See Server setup, Client setup, and UI setup.
Need custom auth/DB hooks or another framework? Continue with Server setup and Client setup.