Skip to content
Files SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Railway Buckets

Railway Buckets (private, Tigris-backed) via the S3-compatible API. Reads the AWS_* variables Railway injects; endpoint defaults to https://t3.storageapi.dev, region to auto.

Installation

@aws-sdk/client-s3, @aws-sdk/s3-presigned-post, and @aws-sdk/s3-request-presigner are optional peer dependencies of files-sdk - install alongside the SDK so the adapter’s imports resolve at runtime.

npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
pnpm add files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
yarn add files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
bun add files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
nub add files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
aube add files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner

upload also needs the optional @aws-sdk/lib-storage package when it uses onProgress, multipart, or a ReadableStream body of unknown length. It’s only loaded then.

Usage

import { Files } from "files-sdk";
import { railway } from "files-sdk/railway";

const files = new Files({
  adapter: railway(),
  // bucket, endpoint, and credentials auto-loaded from
  // AWS_S3_BUCKET_NAME / AWS_ENDPOINT_URL / AWS_ACCESS_KEY_ID /
  // AWS_SECRET_ACCESS_KEY
});

Railway Buckets are private, S3-compatible object storage that runs on Tigris. The adapter is a thin wrapper around the S3 adapter: endpoint defaults to https://t3.storageapi.dev, region defaults to "auto" for signing, and errors are relabelled.

The adapter reads the same AWS_* names that railway bucket credentials prints, so railway() needs no options once a service has them:

Variable Option Bucket reference Notes
AWS_S3_BUCKET_NAME bucket BUCKET The S3 name: your display name plus a short hash. Required.
AWS_ACCESS_KEY_ID accessKeyId ACCESS_KEY_ID Required.
AWS_SECRET_ACCESS_KEY secretAccessKey SECRET_ACCESS_KEY Required.
AWS_ENDPOINT_URL endpoint ENDPOINT Defaults to https://t3.storageapi.dev.
AWS_S3_URL_STYLE forcePathStyle "path" or "virtual". Buckets created before Railway moved to virtual-hosted URLs need "path"; the Credentials tab says which.

In the dashboard, open the service’s Variables tab and auto-inject the bucket’s credentials with the AWS SDK preset. Add any variable from the table the preset didn’t create as a reference to the bucket, for example AWS_S3_BUCKET_NAME=${{my-bucket.BUCKET}}.

Pass the options explicitly to connect from outside Railway:

const files = new Files({
  adapter: railway({
    bucket: "uploads-jdhhd8oe18xi",
    accessKeyId: process.env.RAILWAY_BUCKET_KEY_ID,
    secretAccessKey: process.env.RAILWAY_BUCKET_SECRET,
  }),
});

Credentials never fall back to the AWS credential chain, so a shared AWS profile or instance role can’t end up signing Railway requests. Missing keys throw at construction.

Browser uploads through signedUploadUrl() need a CORS rule on the bucket. Railway’s uploading and serving guide sets one with aws s3api put-bucket-cors.

Options

PropType
bucket?string

The bucket's S3 name: its display name plus a short hash (e.g. `my-bucket-jdhhd8oe18xi`), shown in the bucket's Credentials tab. Falls back to `AWS_S3_BUCKET_NAME`, the name `railway bucket credentials` prints it under; required if that env var isn't set.

Typestring
endpoint?string

Override the S3 endpoint. Falls back to `AWS_ENDPOINT_URL`, then defaults to `https://t3.storageapi.dev`, the endpoint Railway's Credentials tab shows for current buckets.

Typestring
accessKeyId?string

Static access key ID. Falls back to `AWS_ACCESS_KEY_ID`; required if that env var isn't set.

Typestring
secretAccessKey?string

Static secret access key. Falls back to `AWS_SECRET_ACCESS_KEY`; required if that env var isn't set.

Typestring
region?string

SigV4 region used for signing. Defaults to `"auto"`, the value Railway hands out. Buckets are pinned to the region picked at creation, so this is never used for routing, but the signature requires *some* value.

Typestring
forcePathStyle?boolean

Use path-style addressing (`/<bucket>/<key>`) rather than virtual-hosted style. Falls back to `AWS_S3_URL_STYLE` (`"path"` or `"virtual"`), which Railway hands out alongside the credentials. Current buckets use virtual-hosted style; some buckets created before Railway switched need path-style, and their Credentials tab says so.

Typeboolean
publicBaseUrl?string

Origin used to build URLs from `url()`. Railway buckets have no public URLs of their own, so this is for a proxy service or CDN you put in front of the bucket: `url(key)` returns `${publicBaseUrl}/${key}` and skips signing. When unset, `url()` returns a presigned GetObject URL (default expiry: 1 hour).

Typestring
defaultUrlExpiresIn?number

Default expiry, in seconds, for the presigned URLs returned by `url()` when `publicBaseUrl` is not set. Defaults to 3600 (1 hour).

Typenumber

Compatibility

Method Status Notes
upload ✅
download ✅
delete ✅
list ⚠️ The S3 list API returns no per-object Content-Type, so contentType is inferred from the key’s extension (application/octet-stream when unknown). Use head() for the stored value.
search ✅
head ✅
exists ✅
copy ✅
url ✅ Presigned. Railway buckets are private.
signedUploadUrl ✅

Last updated on

Was this page helpful?