An ultrafast, secure, and production-ready file storage API built with the modern JavaScript toolkit: Bun, TypeScript, and Prisma with a PostgreSQL backend.
This project is designed from the ground up for performance, leveraging Bun's native APIs for file I/O, streaming, and serving HTTP requests. It's structured with a clean, scalable architecture and comes with a complete testing and benchmarking suite.
benchmark.mp4
- 🚀 Ultrafast Performance: Utilizes
Bun.file()for zero-copy file streaming and Bun's native HTTP server for minimal overhead. - 🔒 Secure by Default: Endpoints for uploading and deleting are protected by API key authentication.
- 📦 Robust Validation: Enforces server-side validation for maximum file size and allowed MIME types.
- ⚙️ Production-Ready: Features a detailed
/healthendpoint, structured JSON logging with emojis, graceful error handling, and a scalable MVC-like architecture. - 💾 Persistent Metadata: Uses Prisma and PostgreSQL to reliably store file metadata.
- 🧪 Fully Tested: Includes a comprehensive test suite with unit/integration tests and performance benchmarks using
bun:test. - 🧠 Efficient Caching: Implements an in-memory LRU cache for frequently accessed file metadata to reduce database lookups.
- Runtime: Bun
- Language: TypeScript
- ORM: Prisma
- Database: PostgreSQL
- Testing:
bun:test
Follow these instructions to get a local copy up and running.
- Bun (v1.0 or later)
- A running PostgreSQL instance. (You can also run one easily with Docker).
-
Clone the repository:
git clone https://github.com/your-username/bun-storage-server.git cd bun-storage-server -
Install dependencies:
bun install
-
Configure environment variables: Copy the example
.envfile and update it with your own settings.cp .env.example .env
- Update
DATABASE_URLwith your PostgreSQL connection string. - Generate a secure
API_KEYusing:bun -e "console.log(crypto.randomUUID())"
- Update
-
Run the database migration: This will set up the
Filetable in your PostgreSQL database.bunx prisma migrate dev
-
Run the server:
# For development with hot-reloading bun dev # For production bun start
The server will be running at
http://localhost:3000(or your configured port).
All requests requiring authentication must include the x-api-key header.
- Endpoint:
POST /files/upload - Auth: Required
- Body:
multipart/form-datawith a field namedfile.
Example curl request:
curl -X POST http://localhost:3000/files/upload \
-H "x-api-key: YOUR_API_KEY" \
-F "file=@/path/to/your/image.png"Success Response (200 Created):
{
"message": "File uploaded successfully",
"filename": "a1b2c3d4-e5f6-....-g7h8i9j0.png",
"url": "http://localhost:3000/files/a1b2c3d4-e5f6-....-g7h8i9j0.png",
"size": 123456
}- Endpoint:
GET /files/:filename - Auth: Not Required
Example curl request:
curl http://localhost:3000/files/a1b2c3d4-e5f6-....-g7h8i9j0.png -o downloaded_image.png- Endpoint:
DELETE /files/:filename - Auth: Required
Example curl request:
curl -X DELETE http://localhost:3000/files/a1b2c3d4-e5f6-....-g7h8i9j0.png \
-H "x-api-key: YOUR_API_KEY"Success Response (200 OK):
{
"message": "File deleted successfully"
}- Endpoint:
GET /health - Auth: Not Required
Provides server status, database connectivity, uptime, and memory usage.
We use Bun's built-in, high-performance test runner. Tests run against a separate test.db SQLite database for isolation.
-
Run unit/integration tests:
bun test -
Run performance benchmarks:
bun bench
bun-storage-server/
├── prisma/ # Prisma schema and migrations
├── src/ # Source code
│ ├── controllers/ # Request/response logic
│ ├── middlewares/ # Authentication middleware
│ ├── services/ # Business logic & DB interaction
│ ├── utils/ # Helpers (logger, errors, cache)
│ ├── config.ts # Environment variable handling
│ └── index.ts # Server entry point
├── tests/ # Unit tests and benchmarks
├── .env.example # Environment variable template
├── package.json
└── tsconfig.json
Distributed under the MIT License. See LICENSE for more information.