Define a bucket
Name your bucket and choose which files it accepts.
Give a bucket a stable identity, choose a storage profile, and set the files it accepts.
Pre-setup
Complete local Docker storage setup before using the bucket.
It installs the S3/Docker integrations and adds bucket.assets plus defaults.bucket to
defineApp. Docker supplies the local credentials; keep your existing defineEnv contract.
If scaffolding creates a different profile, align it with the definition below.
Scaffold a bucket
From the application root, with an existing assets service:
bun run relkit add bucket Uploads --service assets --provider s3 --source docker
Creates src/services/assets/buckets/uploads.bucket.ts and configures Docker MinIO/S3. Without provider
flags, scaffolding reuses an eligible default/unique profile or creates a Docker S3 profile.
A bucket profile can belong to only one bucket; an already-owned profile is rejected.
Edit the generated bucket’s visibility and file limits. Keep its id and profile; the manual
example below defines a different bucket named assets. Choose one setup path rather than
adding a second bucket for the same files. For the complete HTTP workflow, follow
Upload product images.
Choose a different storage provider
| Selection | Command options |
|---|---|
| Unused compatible profile | --profile uploads |
| Docker MinIO/S3 | --provider s3 --source docker |
| Connected S3 | --provider s3 --source connected |
| S3 on an existing AWS/Pulumi deployment | --provider s3 --source aws |
| Connected Cloudflare R2 | --provider cloudflare-r2 --source connected |
Do not combine --profile with --provider or --source. Cloudflare R2 supports only
connected. AWS requires an existing AWS/Pulumi deployment and is not provisioned by this command.
Set connected-profile environment values yourself; the CLI never asks for credentials.
See Docker startup after adding a resource.
The bucket remains internal; declare it as a function dependency to use it.
For every bucket scaffolding flag, see the bucket command reference.
The scaffold normally installs the selected owners and checks the app. With --no-install, finish
bun install and bun run check. For manual setup, complete the selected adapter installation
first. Connected Cloudflare uses its own package, and connected S3 does not
require a Docker materializer or local MinIO process.
Define the bucket
Use defineBucket in your app’s domain directory. For the manual path, create
src/services/assets/buckets/assets.bucket.ts. If you scaffolded Uploads, apply these policy
options to uploads.bucket.ts while retaining that bucket’s identity and profile:
/** Declares private JSON/image assets with a five-million-byte limit for validated upload handlers. */
import { defineBucket } from "@relkit/app/buckets";
const assets = defineBucket({
id: "assets.objects",
profile: "assets",
visibility: "private",
maxObjectBytes: 5_000_000,
allowedContentTypes: ["application/json", "image/*"],
});
export default assets;
idis the bucket’s stable, unique name. Keep it unchanged when moving or renaming the file.visibilityis required. Start with"private"for user uploads.maxObjectBytessets the maximum size of one file: 5 MB here.allowedContentTypeslists accepted media types.image/*allows image types;application/jsonallows JSON files.profileselects a physical bucket configuration inrelkit.config.ts. This example uses"assets".
Size and content-type limits are optional. For HTTP uploads, also validate incoming files with z.file() as shown in Upload files.
Check your bucket
Make sure the descriptor’s bucket profile exists in relkit.config.ts. The scaffold already
adds its selected profile; the tutorial’s configuration step
shows the assets profile used by the manual example.
Then, from your app’s root, run:
bun run check
Next, give a function access to the bucket. For cloud storage, configure an integration.