dimah-s3v1.5.4

Quickstart

A working S3 upload in minutes — new app or existing project.

Create a new project

Scaffold a full-stack project with preconfigured S3 routes and UI:

npx @dimah-s3/cli@latest create

Manual installation

Install dependencies

npm i @dimah-s3/server @dimah-s3/react @aws-sdk/client-s3

Configure S3 and routes

Define your AWS S3 client and instance. In this example, we create an avatar route for user profile photos:

.env
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_BUCKET="your-bucket-name"
lib/s3.ts
import { S3Client } from "@aws-sdk/client-s3";
import { dimahS3, route } from "@dimah-s3/server";

export const awsS3 = 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 s3 = dimahS3({
  client: awsS3,
  bucket: process.env.S3_BUCKET!,
  routes: {
    avatar: route({
      upload: {
        fileTypes: ["image/*"],
        maxFileSize: 2 * 1024 * 1024, // 2MB
      },
    }),
  },
});

Mount the route handler

app/api/s3/[...s3]/route.ts
import { toNextJsHandler } from "@dimah-s3/server/next";
import { s3 } from "@/lib/s3";

export const { GET, POST, PUT, PATCH, DELETE } = toNextJsHandler(s3);

Create the client client & provider

lib/s3-client.ts
"use client";

import { createS3Client } from "@dimah-s3/react";

export const s3Client = createS3Client();
export const S3Provider = s3Client.Provider;

Wrap your application

npm i @dimah-s3/ui shadcn
app/globals.css
@import "shadcn/tailwind.css";
@import "@dimah-s3/ui/styles.css";

/* + shadcn theme variables (`--primary`, `--muted`, …) */

/* Optional: theme dimah-s3 independently of the rest of the app
@theme {
  --color-dimah-s3-primary: oklch(0.65 0.15 150);
}
*/
app/layout.tsx
import { Toaster } from "@dimah-s3/ui";
import { S3Provider } from "@/lib/s3-client";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <S3Provider>{children}</S3Provider>
        <Toaster />
      </body>
    </html>
  );
}

Add an upload button

app/page.tsx
"use client";

import { useUpload } from "@dimah-s3/react";
import { UploadButton } from "@dimah-s3/ui";

export default function AvatarUploadPage() {
  const upload = useUpload({ route: "avatar" });

  return <UploadButton upload={upload} />;
}

Selecting an image presigns a secure URL and uploads directly to your bucket under avatar/{uuid}/{filename}.

Frequently asked questions

On this page