v0.1.0 Released — Runtime Agnostic File Storage Engine

One standard API for all your file storage. Zero dependencies.

Stream files effortlessly across Node.js, Cloudflare Workers, Bun, and Deno. Swap between Local, S3, and Cloudinary drivers with a single line of code.

install.sh
$npm install @fileway/core @fileway/driver-s3

One Client. Any Driver.

Switch backends — not your code

The FilewayClientAPI never changes. Only the driver config. Full TypeScript inference adapts to each driver's metadata.

Driver Info

Local

Local filesystem via Node.js streams

import { FilewayClient } from "@fileway/core"
import { LocalDriver } from "@fileway/driver-local"

const client = new FilewayClient({
  driver: new LocalDriver({
    directory: "./uploads",
    baseUrl: "/files",
  }),
})

// TypeScript infers result.meta.localPath
const result = await client.upload(stream, {
  filename: "profile.jpg",
  metadata: { userId: "usr_123" },
})

Full TypeScript inference — your IDE knows exactly what each driver returns

Built for scale

Everything you need, nothing you don't

core

Zero Dependencies Core

Less than 2kB gzipped with zero external node modules. Pure Web Streams, fetch, and Web Crypto.

deps: 0
size: 1.8kB
core

True Web Streams

Standard ReadableStream<Uint8Array> from upload to driver. No buffers, no memory spikes.

core

Universal Edge Ready

Deploy anywhere — Node.js 20+, Bun, Deno, Cloudflare Workers, Vercel Edge, Lagon.

Node.jsBunDenoCF WorkersVercel Edge
core

Strict Metadata Inference

Each driver exposes typed metadata. Autocomplete adapts to your backend — no runtime surprises.

result.meta.publicId // Cloudinary
result.meta.localPath // Local
core

Composable Middleware

beforeUpload / afterUpload hooks for validation, compression, logging, and thumbnail generation.

Developer Experience

From 50 lines to 5

No more vendor-specific SDKs, stream conversions, or fragile error handling. One API. End-to-end type safety.

The Old Way
// AWS SDK v3 — 50+ lines per provider
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
import { Readable } from "node:stream"

const s3 = new S3Client({ region: "us-east-1" })

async function uploadToS3(
  buffer: Buffer,
  key: string
): Promise<string> {
  // Manual stream → buffer conversion
  const command = new PutObjectCommand({
    Bucket: "my-bucket",
    Key: key,
    Body: buffer,
  })
  
  try {
    await s3.send(command)
    return `https://s3.amazonaws.com/my-bucket/${key}`
  } catch (err) {
    // Per-provider error handling
    console.error("S3 upload failed:", err)
    throw err
  }
}
The Fileway Way
import { FilewayClient } from "@fileway/core"
import { S3Driver } from "@fileway/driver-s3"

const client = new FilewayClient({
  driver: new S3Driver({
    bucket: "my-bucket",
    region: "us-east-1",
  }),
})

// Accepts ReadableStream<Uint8Array> directly
const result = await client.upload(stream, {
  filename: "report.pdf",
})

console.log(result.url)  // Fully typed

Same client works with Local, S3, Cloudinary, and more. Just swap the driver.