Express File Upload
Upload Files from Express Route Handlers (Drop multer + aws-sdk)
Upload files from Express route handlers with fetch or axios. No SDK, REST API, CDN delivery.
The classic Express upload stack is multer to parse multipart, aws-sdk to push to S3, and a pile of IAM and bucket config to make it work. files.link collapses that into three HTTP calls from your route handler — using Node's built-in fetch (Node 18+) or axios — and the headline win is that you can skip multer entirely for the common case by streaming the raw request body straight to the presigned URL.
If your client sends the file as a raw binary body (the simplest case), you never buffer it on disk:
import express from 'express';
const app = express();
const KEY = process.env.FILESLINK_KEY;
const BASE = 'https://api.files.link';
app.post('/upload', express.raw({ type: '*/*', limit: '50mb' }), async (req, res) => {
const r1 = await fetch(`${BASE}/v1/files/${process.env.FOLDER_ID}`, {
method: 'POST',
headers: { Authorization: KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ filesMetadata: [{ name: req.query.name, size: req.body.length, type: req.headers['content-type'] }] }),
});
const slot = (await r1.json()).urls[0];
await fetch(slot.url, { method: 'PUT', headers: { 'Content-Type': req.headers['content-type'] || 'application/octet-stream' }, body: req.body });
await fetch(`${BASE}/v1/files/confirm-upload`, {
method: 'POST',
headers: { Authorization: KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ ids: [slot.id] }),
});
res.json({ id: slot.id });
});If you must accept a browser multipart/form-data form, you still need a parser — but reach for busboy or formidable, not multer, because you only want the file stream, not multer's disk/memory storage engines. Pipe the parsed file stream directly to the presigned PUT; Node fetch accepts a ReadableStream as the body, so a large upload never fully lands in process memory. Prefer axios? The same three calls work — set responseType and pass a stream as data.
Keep the API key in process.env.FILESLINK_KEY (via dotenv in dev, host secrets in prod) and send it as the raw Authorization value with no Bearer prefix. You get back CDN-backed URLs with per-file visibility, storage encrypted at rest, and prepaid-credit billing instead of a metered S3 egress invoice — no IAM user, no bucket policy, no SDK in node_modules.
Benefits With No Complexity
Global CDN delivery
Edge-cached worldwide
Signed-URL security
What You Get
Unlimited files
Unlimited storage
Public + Private storage
CDN ready links
Prepaid credits
More coming soon
How files.link Works
1. Upload
2. Copy
3. Use Anywhere
Why Developers Choose files.link
A Better Way to Store & Deliver Files
| multer + aws-sdk | Cloudinary (multer-storage-cloudinary) | files.link | |
|---|---|---|---|
| No multer middleware required | |||
| No SDK install (built-in fetch / axios) | |||
| Stream request body straight to storage | |||
| Global CDN delivery on every file | |||
| Prepaid credits (no surprise bills) |
Calculate Your Needs
Storage
Egress
CDN Bandwidth
Wire Up Express File Uploads
- Global CDN delivery
- Edge-cached worldwide
- Signed-URL security
- Unlimited files
- Unlimited storage
- Public + Private storage
- No subscription — prepaid credits keep spend predictable