https://blog.spin.rip/p/discord-cdn-changes
A simple website that allows you to upload files to Discord's CDN without having to do it in their app.
Git (optional)
git clone https://github.com/spinfal/cdn-slave.git
or download the ZIP file and extract it
cd cdn-slave
- Rename Global.example.js to
Global.js - Go to https://discord.com/developers/applications and create bot
- Make sure this is enabled
- Invite the bot to your server using this link:
https://discord.com/api/oauth2/authorize?client_id=INSERT YOUR APPLICATION ID&permissions=52224&scope=bot - Configure the
Global.jsfile (bot, channel, and database settings)
npm i
npm run setup
This creates Global.js if missing, initializes the SQLite database, and builds CSS.
npm run db:init
If you skip setup, run db:init manually.
npm run start
or
npm run dev
The website will be up @ http://localhost:443 (unless you've changed the config)
Files uploaded on the site will be available in the channel that you set in Global.js
If you want custom URLs to point at your domain, set publicUrl in Global.js.
SQLite stores data in a local file at data/cdn-slave.sqlite by default.
To move it elsewhere, update database.filename in Global.js.
Uploads use the size limit from maxFileSize and run through rate limiting, MIME checks, and concurrency caps.
Adjust these settings in Global.js:
upload.rateLimit.windowMsandupload.rateLimit.max(per-IP requests)upload.maxConcurrent(simultaneous uploads)upload.allowedMimeTypesandupload.allowedMimePrefixesupload.tempDir(where temporary upload files are stored)
The defaults allow common media formats plus PDF/ZIP. Update the allow lists if you want other file types. Set both allow lists to empty arrays if you want to accept any MIME type.
GET /health returns {"status":"ok"} when the server and database are reachable.
logLevel controls server logging verbosity, and defaultTimezone is used as the fallback for server-side timestamps before the browser converts them to the viewer's timezone.
CDN Slave can also be used with ShareX! Follow these steps to get it working (don't want to follow steps? click here to download the config):
- Copy the upload endpoint. If using localhost it will be
http://localhost:443/api/upload, or if you're using my instance it will behttps://cdn-slave.spin.rip/api/upload - Open ShareX and go to
Destinations>Custom uploader settings> ClickNew - Name it whatever you want & paste the upload endpoint in
Request URL - Under
Destination type, selectImage uploader,Text uploader, andFile uploader - Body should be
Form data (multipart/form-data)andFile form nameshould just befile. - In the headers section, set the name to
Upload-Sourceand the value toAPI - Select your new ShareX config in the dropdowns at the bottom left of your screen
- Have fun with your new CDN slave.

