Express
Integrate MediaLit with Express
This setup uses the medialit server-side SDK with Express and multer.
You can find a runnable reference app in examples/express.
1. Install dependencies
pnpm add express multer medialit cors2. Add environment variables
MEDIALIT_API_KEY=your_api_key_here
# Optional for self-hosted MediaLit
MEDIALIT_ENDPOINT=http://localhost:3001
PORT=40003. Create Express server
Create server.js (or server.ts) and add:
import express from "express";
import cors from "cors";
import multer from "multer";
import { readFile, unlink } from "node:fs/promises";
import { MediaLit } from "medialit";
const app = express();
const upload = multer({ dest: "uploads/" });
const client = new MediaLit();
app.use(cors());
app.use(express.json());
// Upload via server
app.post("/api/medialit/upload", upload.single("file"), async (req, res) => {
try {
if (!req.file) return res.status(400).json({ error: "file is required" });
if (!process.env.MEDIALIT_API_KEY) {
return res.status(500).json({ error: "MEDIALIT_API_KEY is missing" });
}
const bytes = await readFile(req.file.path);
const formData = new FormData();
formData.append(
"file",
new Blob([bytes], { type: req.file.mimetype }),
req.file.originalname || req.file.filename,
);
formData.append("access", req.body.access === "public" ? "public" : "private");
if (req.body.caption) formData.append("caption", req.body.caption);
if (req.body.group) formData.append("group", req.body.group);
const uploadResponse = await fetch(`${client.endpoint}/media/create`, {
method: "POST",
headers: {
"x-medialit-apikey": process.env.MEDIALIT_API_KEY,
},
body: formData,
});
const media = await uploadResponse.json();
if (!uploadResponse.ok) throw new Error(media.error || "Upload failed");
if (!media.mediaId) throw new Error("Upload succeeded but mediaId is missing");
// Seal uploaded media so it persists and appears in list/get APIs.
const sealedMedia = await client.seal(media.mediaId);
// cleanup temp file
await unlink(req.file.path).catch(() => undefined);
return res.json(sealedMedia);
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
// List media
app.get("/api/medialit", async (req, res) => {
try {
const page = Number.parseInt(String(req.query.page ?? "1"));
const limit = Number.parseInt(String(req.query.limit ?? "10"));
const access = req.query.access;
const group = req.query.group;
const media = await client.list(page, limit, {
access: access === "public" || access === "private" ? access : undefined,
group: typeof group === "string" ? group : undefined,
});
return res.json(media);
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
// Get media by id
app.get("/api/medialit/:id", async (req, res) => {
try {
const media = await client.get(req.params.id);
return res.json(media);
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
// Delete media
app.delete("/api/medialit/:id", async (req, res) => {
try {
await client.delete(req.params.id);
return res.json({ success: true });
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
// Count media
app.get("/api/medialit/count", async (_req, res) => {
try {
const count = await client.getCount();
return res.json({ count });
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
// Optional: signature for browser direct upload
app.post("/api/medialit/signature", async (req, res) => {
try {
const signature = await client.getSignature({
group: req.body.group,
});
return res.json({
endpoint: client.endpoint,
signature,
});
} catch (error) {
return res
.status(500)
.json({ error: error instanceof Error ? error.message : "Unknown error" });
}
});
const port = Number(process.env.PORT ?? 4000);
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});4. Start server
node --env-file=.env server.js5. Test upload endpoint
curl -X POST http://localhost:4000/api/medialit/upload \
-F "file=@/absolute/path/to/image.jpg" \
-F "access=public" \
-F "caption=My first upload"This example seals uploaded media as part of the same /api/medialit/upload route:
const sealedMedia = await client.seal(media.mediaId);
return res.json(sealedMedia);If you remove that line from the route, uploaded files may not persist or appear in list/get results.
6. Get media list
curl "http://localhost:4000/api/medialit?page=1&limit=10"Optional filters:
curl "http://localhost:4000/api/medialit?page=1&limit=10&access=public"
curl "http://localhost:4000/api/medialit?page=1&limit=10&group=my-group"7. Notes
- Keep
MEDIALIT_API_KEYserver-side only. medialitSDK is Node.js server-only and should not run in browser code.- For large client-side uploads, use
/api/medialit/signature+ TUS upload from the frontend. - Seal uploaded files (
client.seal(mediaId)) to persist them and make them show up in list/get results.