Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

JavaScriptintermediatebackendAI generated

Image Upload API

Build an image upload service in JavaScript: a Node.js API accepts image uploads, checks they are real images within the size limits, creates thumbnails in a few sizes with the sharp library, and returns information about each image (dimensions, format, file size and thumbnail URLs), plus a small React page built with Vite for uploading by drag and drop with progress bars and previews. The service strips hidden metadata such as GPS location from photos, detects duplicate uploads, and never leaves half-processed files behind. You'll learn handling file uploads safely, image processing with sharp, streaming, designing an API response, building an upload interface with progress, and testing.

Estimate
~11h
Steps
6
Completed by
0
Proposed by
codeseed.app

Node.js · Express · sharp · Vite · React

Project roadmap

  1. 01

    Define the API

    ~1.5h

    Write API.md: POST /images (multipart form upload), GET /images/:id (metadata and thumbnail URLs), GET /images (a paginated list) and DELETE /images/:id, the limits (maximum file size, maximum dimensions, allowed formats JPEG, PNG and WebP, and at most 10 files per request), the thumbnail sizes (for example 150, 400 and 1200 pixels wide) and the error format. Done when: API.md defines the endpoints, limits and errors.

  2. 02

    Accept uploads safely

    ~2h

    Build the server with Express and multer (or busboy), enforcing the size and file count limits while receiving. Check the real type from the file's first bytes (for example with the file-type package), not the name, and read the dimensions with sharp's metadata(), refusing images too large before processing them. Store originals under random names outside the public folder. Done when: a renamed text file, an oversized file and a huge-dimension image are rejected with clear errors.

  3. 03

    Create thumbnails

    ~2h

    With sharp, rotate each image according to its EXIF orientation, remove its metadata (including GPS), and create the thumbnail sizes in WebP (without enlarging small images). Write outputs to temporary files and move them into place only when all succeeded, cleaning up otherwise. Done when: uploads produce correctly oriented thumbnails with no metadata.

  4. 04

    Store metadata and detect duplicates

    ~1.5h

    Store each image's metadata in SQLite (or a JSON store): id, original name, format, dimensions, file size, SHA-256 checksum (unique), thumbnails and created time. When the same checksum is uploaded again, return the existing image instead of processing it again. Implement the list and delete endpoints (deleting files too). Done when: duplicate uploads return the existing image, and deletes remove everything.

  5. 05

    Build the upload page

    ~2h

    Build a React page with Vite: a drop zone and file picker, a check of type and size before uploading, uploads with progress bars (using XMLHttpRequest's upload progress event, since fetch doesn't report it), previews of the returned thumbnails, and clear error messages per file. Show a gallery of uploaded images with delete buttons. Done when: several images can be dropped and uploaded with visible progress.

  6. 06

    Test it

    ~2h

    Write tests with Vitest and supertest using small generated images: each validation rule, thumbnail sizes and orientation, metadata removal, duplicate detection, cleanup after a simulated processing failure, and listing and deleting. Done when: all tests pass.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~11h · 6 steps

Tech stack

Node.jsExpresssharpViteReact