Escape hatch

Drop down to the native, per-adapter client for any feature outside the unified surface — versioning, lifecycle rules, ACLs, object tags, and more.

The unified surface is deliberately small — the methods every adapter can implement. When you need a provider feature that isn't part of it (S3 versioning, lifecycle rules, ACLs, object tags, anything), drop down to the native client instead of waiting for it to be wrapped.

files.raw

raw is the underlying provider client, typed per adapter — S3Client for s3(), VercelBlobClient for vercelBlob(), an R2Bucket (or S3Client in HTTP mode) for r2(), and so on. The type flows through from the adapter, so you keep full autocomplete on it.

const files = new Files({ adapter: s3({ bucket: "uploads" }) });

// `files.raw` is typed as S3Client — no cast needed.
await files.raw.send(
  new PutObjectAclCommand({
    Bucket: "uploads",
    Key: "a.png",
    ACL: "public-read",
  })
);

files.adapter is the adapter itself, if you need its name or want to pass it around; files.adapter.raw is the same client as files.raw.

What raw bypasses

The native client talks to the provider directly, so none of the Files wrapper's behavior applies to calls you make through it:

  • No prefix scoping. You pass the provider's full key yourself, including any prefix the Files instance was constructed with — files.raw doesn't know about it.
  • No normalized errors. A failure throws the provider's own error type, not a FilesError; catch and classify accordingly.
  • No hooks, retries, timeouts, or cancellation. Hooks don't fire, and signal / timeout / retries aren't applied. Use the provider client's own equivalents.

In short, raw is an unmanaged door straight to the provider. Reach for it for the one feature you need, and keep using the unified methods for everything else.

Keeping the type

The raw type is inferred from the adapter you pass in, so it stays typed as long as the instance keeps its concrete type. Widening to the bare Files (whose adapter is the default Adapter) erases it:

const files = new Files({ adapter: s3({ bucket: "uploads" }) });
files.raw; // S3Client

const widened: Files = files;
widened.raw; // unknown

If you store a Files instance on a typed field, annotate it with the adapter's type (for example Files<S3Adapter>) rather than the bare Files, and raw stays typed.

See the Compatibility section on each adapter's docs page for what it supports through the unified surface before reaching for the escape hatch.

On this page