# Local storage (/docs/local-development/storage)

> For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL.

Use S3-compatible client libraries against Prisma object storage, locally with stand-in buckets and deployed on Prisma Compute.

Location: Local Development > Local storage

[Object Store buckets](https://www.prisma.io/docs/storage) speak the S3 API. Because your app talks to storage through an ordinary S3 client, the same code runs against a local stand-in bucket during development and a hosted bucket on [Prisma Compute](https://www.prisma.io/docs/compute). Nothing in your upload or download paths knows which one it is using.

## Local buckets with dev [#local-buckets-with-dev]

Apps deploy to Compute as [Prisma Composer](https://www.prisma.io/docs/composer) apps, and `dev` provisions a local stand-in bucket with working credentials, so upload code runs locally without an account or cloud credentials. Declare the bucket as a dependency and the service receives `{ url, bucket, accessKeyId, secretAccessKey }` from `service.load()`, the standard S3 config set, whether the bucket is local or hosted. Those four values are what your S3 client needs: pass them as its endpoint, bucket name, and credentials rather than reading them from environment variables. See [Object storage in Composer](https://www.prisma.io/docs/composer/object-storage) and [Local development in Composer](https://www.prisma.io/docs/composer/local-development).

You can also develop against a hosted bucket directly: create one with the [`bucket` CLI commands](https://www.prisma.io/docs/cli/bucket) and mint a scoped access key. The key's credentials work from your machine during development the same way they work from a deployment.

## S3-compatible clients on Compute [#s3-compatible-clients-on-compute]

Any S3 client or SDK works with buckets. The examples below use direct access-key configuration through environment variables, the shape that fits a hosted bucket with a minted key. In a Composer service, feed the client the values from `load()` instead; the client setup is otherwise identical.

### Bun's built-in S3 client [#buns-built-in-s3-client]

Compute runs deployed apps on Bun, and Bun ships an [S3 client](https://bun.com/docs/api/s3) that reads `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY_ID`, and `S3_SECRET_ACCESS_KEY` from the environment. With those four variables set, reading, writing, and presigning need no client configuration and no dependency:

```ts title="src/storage.ts"
// Write an object, then hand out a time-boxed download URL.
await Bun.s3.file("uploads/hello.txt").write("hello from a bucket");

const url = Bun.s3.file("uploads/hello.txt").presign({ expiresIn: 3600 });
```

[Object storage on Compute](https://www.prisma.io/docs/compute/object-storage) builds this into a deployed upload-and-serve route end to end.

### AWS SDK (@aws-sdk/client-s3) [#aws-sdk-aws-sdkclient-s3]

If your app already uses the AWS SDK, point it at the bucket's endpoint and credentials. These are the same four values Bun reads from the environment; in a Composer service they arrive through `load()` and slot into the same fields:

```ts title="src/storage.ts"
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: "auto",
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY_ID!,
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  },
});

await s3.send(
  new PutObjectCommand({
    Bucket: process.env.S3_BUCKET,
    Key: "uploads/hello.txt",
    Body: "hello from a bucket",
  }),
);
```

The SDK requires a `region`; S3-compatible endpoints ignore it, so `"auto"` is fine. Other S3-compatible libraries, such as `minio`, configure the same way: endpoint, bucket name, key id, secret.

## Next steps [#next-steps]

* [Storage](https://www.prisma.io/docs/storage): buckets, access keys, and management surfaces.
* [Object storage on Compute](https://www.prisma.io/docs/compute/object-storage): a deployed upload-and-serve route, step by step.
* [Object storage in Composer](https://www.prisma.io/docs/composer/object-storage): the declarative `bucket()` resource.

## Related pages

- [`Local app`](https://www.prisma.io/docs/local-development/app-development): Run your app locally on the runtime Prisma Compute deploys, wire it to a local database, and bring up the whole app with Composer.
- [`Local Postgres`](https://www.prisma.io/docs/local-development/postgres): Set up and use Prisma Postgres for local development