Quickstart
Add file uploads to an existing Next.js app in under 5 minutes.
Need an API key? Create a free account at app.uploadkit.dev to get one.
This quickstart adds UploadKit to an existing Next.js project. Most people land here — that's the path we optimize for. If you're starting from a blank slate, see Starting a new project at the bottom.
Install packages
Add @uploadkitdev/next (server-side handler) and @uploadkitdev/react (UI components) to your project:
pnpm add @uploadkitdev/next @uploadkitdev/reactnpm install @uploadkitdev/next @uploadkitdev/reactyarn add @uploadkitdev/next @uploadkitdev/reactbun add @uploadkitdev/next @uploadkitdev/reactCreate the file router
Create app/api/uploadkit/[...uploadkit]/route.ts (catch-all segment) and define which files your app accepts:
import { createUploadKitHandler } from '@uploadkitdev/next';
import type { FileRouter } from '@uploadkitdev/next';
const router = {
default: {
maxFileSize: '4MB',
allowedTypes: ['image/*'],
onUploadComplete: async ({ file, metadata }) => {
// Persist file info to your database
console.log('Upload complete:', file.url);
},
},
} satisfies FileRouter;
export const { GET, POST } = createUploadKitHandler({
router,
apiKey: process.env.UPLOADKIT_API_KEY!,
});Using satisfies FileRouter (not a type annotation) preserves the literal route names — this is what makes the client components fully type-safe.
Set environment variables
Add your API key to .env.local:
UPLOADKIT_API_KEY=uk_live_xxxxxxxxxxxxxxxxxxxxxUPLOADKIT_API_KEY— server-side only. It's read bycreateUploadKitHandlerand never exposed to the browser. Never prefix withNEXT_PUBLIC_.
Wrap your root layout
Add UploadKitProvider to app/layout.tsx, pointing it at the route handler you created:
import { UploadKitProvider } from '@uploadkitdev/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<UploadKitProvider endpoint="/api/uploadkit">
{children}
</UploadKitProvider>
</body>
</html>
);
}Drop in a dropzone
Drop <UploadDropzone> into any page and point it at your route. The route prop is required and must match a key in your file router:
import { UploadDropzone } from '@uploadkitdev/react';
export default function Page() {
return (
<main>
<h1>Upload a file</h1>
<UploadDropzone
route="default"
onUploadComplete={(files) => {
console.log('Uploaded:', files);
}}
/>
</main>
);
}That's it. You now have working file uploads with type validation, size limits, and direct-to-storage transfers via presigned URLs — no server bottleneck.
Starting a new project
If you're scaffolding from scratch (not adding to an existing app), skip the setup above and run:
npx create-uploadkit-app my-appIt asks two questions (template + package manager), wires up a working upload page, and you're done. Templates: next · sveltekit · remix · vite. See the CLI guide for the full flag reference.
Using an AI-assistant IDE?
Claude Code, Cursor, Windsurf, Zed
Install the UploadKit MCP server so your assistant has first-class knowledge of every component and can wire the route handler, provider, and .env.local for you. npx -y @uploadkitdev/mcp — no API key required.
Next steps
- Next.js App Router guide — full setup with multiple routes, middleware, and type-safe helpers
- React / Vite guide — for non-Next.js React apps
- API Only guide — for any language via REST API
- CLI reference —
create-uploadkit-appflags and templates - Theming — customize colors, radius, and dark mode
- Bring Your Own Storage — use your own S3 or R2 bucket