# Introduction (/docs)



s3.delivery is a file-storage SDK for TypeScript apps. Files go **straight from
the browser to your own bucket** through short-lived presigned URLs — they never
pass through your server or ours. Your code only signs and authorizes; the bytes
take the direct path.

You get fast uploads, cheap bandwidth (no proxy egress to pay for), and no vendor
lock-in (the files live in your own S3-compatible bucket). One API key wires up
the whole thing.

```ts
import { S3Delivery } from "s3delivery";

const s3 = new S3Delivery(); // reads S3DELIVERY_TOKEN
const file = await s3.upload(blob, { name: "report.pdf" });

console.log(file.url); // a stable link, ready to share
```

That is the whole upload: reserve a record → send bytes straight to your bucket →
confirm — in one call.

<Cards>
  <Card title="Quickstart" href="/docs/quickstart" icon="Rocket">
    One API key, one mounted route, uploads from the browser.
  </Card>

  <Card title="How it works" href="/docs/architecture" icon="Network">
    The browser → bucket model, and why it is cheap and fast.
  </Card>

  <Card title="Projects" href="/docs/projects" icon="FolderOpen">
    Group files by app, environment, customer, or agent workflow.
  </Card>

  <Card title="Server client" href="/docs/server-client" icon="Server">
    `new S3Delivery()` and every method it exposes.
  </Card>

  <Card title="AI agents" href="/docs/ai-agents" icon="Bot">
    Give an agent file tools in one line with `s3delivery/ai`.
  </Card>

  <Card title="Public MCP" href="/docs/mcp" icon="Terminal">
    Let coding agents fetch install snippets and the s3.delivery skill.
  </Card>
</Cards>

## The browser → bucket model [#the-browser--bucket-model]

A typical upload SDK proxies your file through the vendor's storage: the browser
sends bytes to the vendor, the vendor stores them, and you fetch them back through
the vendor again. You pay for that bandwidth and inherit that latency.

s3.delivery splits the work in two:

* **Control plane** — a small Worker API checks your API key, enforces quota and
  per-route constraints, writes a metadata row, and mints a presigned URL. Every
  request is a quick signing + database operation.
* **Data plane** — the browser (or your server) `PUT`s the bytes **directly to
  your bucket** using that presigned URL. The API never sees a byte.

Downloads work the same way in reverse: the API checks permissions and signs a
short-lived GET URL, and the browser reads straight from the bucket.

## What you get [#what-you-get]

* **One API key.** No file-router DSL and no per-bucket config. Mount one route
  and call one function.
* **Bytes skip the API.** Browser → bucket directly, so uploads are fast and you
  do not pay for proxy bandwidth.
* **Locally signed downloads.** Download URLs are signed without an extra API
  round-trip.
* **Reliable completion.** A synchronous confirm step verifies the object really
  landed in the bucket — no webhooks and no dev tunnels.
* **Your bucket, no lock-in.** Files live in your own S3-compatible bucket.
* **Parallel + multipart, built in.** Batches upload several files at once; large
  files split into parts that upload concurrently — automatically.
* **AI-agent native.** `s3delivery/ai` turns the client into ready-made tools for
  the [Vercel AI SDK](https://ai-sdk.dev), with read-only and approval gates.
* **Public MCP for coding agents.** The public MCP is intentionally tiny: it
  helps agents write integration code, but it cannot access your account or
  files.

## Add uploads in \~5 lines [#add-uploads-in-5-lines]

Server-side, end to end:

```ts
import { S3Delivery } from "s3delivery";

const s3 = new S3Delivery();
const file = await s3.upload(blob, { name: "report.pdf" });
file.url;
```

From the browser, with the React hook:

```tsx
import { useUploadFiles } from "s3delivery/react";

const { upload, uploadedFiles, progress, isPending } = useUploadFiles();

<input type="file" multiple onChange={(e) => upload(e.target.files!)} />;
```

Head to the [Quickstart](/docs/quickstart) to set up the route handler that keeps
your key on the server.

## Install [#install]

<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npm i s3delivery
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm add s3delivery
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn add s3delivery
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun add s3delivery
    ```
  </CodeBlockTab>
</CodeBlockTabs>

The package ships three entry points:

| Import             | Use it for                                                          |
| ------------------ | ------------------------------------------------------------------- |
| `s3delivery`       | Server client, route handler, and the framework-free uploader.      |
| `s3delivery/react` | React hooks and the prebuilt `<UploadButton>` / `<UploadDropzone>`. |
| `s3delivery/ai`    | File tools for the Vercel AI SDK. `ai` is an optional peer dep.     |

`react` and `ai` are optional peer dependencies — the core SDK only depends on
`zod`.
