---
name: bijection-convex-railway-buckets
description: "Evaluate and integrate the Railway Buckets component with Bijection."
---

# Railway Buckets

Store files in Railway Buckets from Convex, with presigned browser uploads, access checks, and file metadata kept in Convex.

This is an upstream package. It has not been adapted or qualified for Bijection.

- Package: convex-railway-buckets
- Source: https://github.com/leoisadev1/convex-railway-buckets
- npm: https://www.npmjs.com/package/convex-railway-buckets
- Directory: https://bijection.com/components/convex-railway-buckets

Read the upstream README for setup, license, and compatibility before using it.

## Integration workflow

1. Read the source README and package manifest at the recorded revision.
2. Confirm the required SDK, dependency availability, and runtime compatibility.
3. Follow the component's documented setup and configuration. Never invent an npm install command from a catalog package name.
4. Keep credentials in the project's existing secret store.
5. Follow the project's execution rules for verification and report what was actually checked.

## Original upstream skill

The following guidance describes convex-railway-buckets. Its installation commands and APIs refer to the upstream package. Evaluate compatibility with the Bijection source separately.


> Agents: read this skill fully before writing code that uses Railway Buckets. Follow the installation and configuration steps exactly.

# Railway Buckets

## Instructions

Railway Buckets is a Convex component that integrates Railway's S3-compatible object storage with your Convex backend. Browsers upload files directly to the bucket via presigned PUT URLs signed with a built-in SigV4 implementation, while Convex stores and queries file metadata reactively. Upload policies, access checks, and post-upload hooks all run inside Convex transactions, keeping your file records consistent with the rest of your data.

### Installation

```bash
npm install convex-railway-buckets
```

Current npm version: `convex-railway-buckets@0.1.0`

## Use cases

- Adding user file uploads (images, documents, CSVs) to a Convex app without routing file bytes through your backend functions
- Enforcing per-upload size and content type limits at the storage layer, with Railway rejecting any non-conforming PUT request
- Gating file reads behind auth checks using presigned GET URLs or a stable HTTP redirect route for use in img src tags
- Generating and storing server-side files (reports, exports) from Convex actions and writing them directly to the bucket with buckets.store()
- Running multiple isolated buckets in one Convex deployment by installing the component multiple times under different names

## How it works

Setup involves installing the component, running the provided CLI command to pipe Railway bucket credentials into Convex environment variables, and declaring those env vars in convex.config.ts with app.use(railwayBuckets, { env: { ... } }). Convex validates that all three required vars (BUCKET, ACCESS_KEY_ID, SECRET_ACCESS_KEY) are present at deploy time, so missing credentials surface at npx convex dev rather than at runtime.

The upload flow is a three-step protocol: the client calls generateUploadUrl to get a presigned PUT URL and required headers, uploads directly to Railway, then calls verifyUpload (which HEADs the object) and completeUpload (which records the file and runs the onUpload hook in a single transaction). Each URL is signed for one exact size and content type, includes a random upload ID in metadata, and uses a conditional write so replaying the URL cannot overwrite an existing object.

File metadata lives in Convex tables, so listFiles and getFile return paginated, reactive results alongside presigned GET URLs. Railway buckets are private, so all reads go through signed URLs (default 1-hour expiry) or through a stable HTTP route registered with buckets.registerRoutes(http, { pathPrefix }) that issues a fresh 302 redirect per request. Deletions are durable: the file record is removed immediately and the actual object deletion is retried in the background until Railway confirms it.

The component ships a useUploadFile React hook and a framework-agnostic uploadFile function from convex-railway-buckets/browser for use with Svelte, Vue, or plain JS. Testing is supported via convex-test by importing railwayBuckets from convex-railway-buckets/test and calling railwayBuckets.register(t).

## When NOT to use

- When a simpler built-in solution exists for your specific use case
- If you are not using Convex as your backend
- When the functionality provided by Railway Buckets is not needed

## Resources

- [npm package](https://www.npmjs.com/package/convex-railway-buckets)
- [GitHub repository](https://github.com/leoisadev1/convex-railway-buckets)
- [Live demo](https://github.com/leoisadev1/convex-railway-buckets/tree/main/example)
- [Convex Components Directory](https://www.convex.dev/components/convex-railway-buckets)
- [Convex documentation](https://docs.convex.dev)