npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

sharex-server

v2.2.0

Published

ShareX image and file hosting using Node.js

Readme

sharex-server

A tiny, self-hosted upload target for ShareX and similar clients. Runs on Node.js and stores uploads on disk.

⭐ Features

  • File uploads (including text, image, GIF, MP4 etc)
  • Simple files directory listing with configurable endpoint
  • Downloadable .sxcu file endpoint (/api/sxcu)
  • Setting Base URL

Quickstart

Docker is the recommended way to run ShareX-Server! (see Docker Hub).

Manually in your Node app:

  • npm install sharex-server
  • import { ShareXServer } from "sharex-server";
    new ShareXServer({ password: "s3cret", port: 8080, savePath: "./uploads" });

Options

All options accepted by the ShareXServer constructor:

  • password (string) - REQUIRED. The password clients must send as the x-password header to upload files.
  • port (number, default 8080) - TCP port the server listens on.
  • baseUrl (string, default /) - Base URL the server will run on.
  • savePath (string, default ./uploads) - Filesystem directory where uploads are stored. The server ensures this directory exists. On Windows prefer an absolute path to avoid a leading / being prefixed when resolving.
  • filenameLength (number, default 10) - Length passed to nanoid() used to generate short random filenames.
  • enableSxcu (boolean, default false) - When true the server exposes a simple endpoint to get a downloadable .sxcu at GET /api/sxcu.
  • fileListing (string | false, default files) - Path to file listing of uploads. Set to false to disable the listing.
  • debug (boolean, default false) - Enable verbose debug logging to the console.
  • forceHttps (boolean, default false) - Force HTTPS for return URL (useful when running behind reverse proxy)

Usage notes:

  • The server saves uploaded files directly under savePath and will serve any file in that directory - do not point savePath at directories containing sensitive data.
  • The upload flow is protected only by the x-password header - run behind HTTPS and/or restrict access with a firewall or reverse proxy for production deployments.

Uploading

  • Endpoint: POST /api/upload (multipart form, field name file).
  • Auth: include header x-password: <your-password>.
  • Success response: JSON containing a url pointing to the uploaded file.

Example (PowerShell / pwsh):

curl -X POST "http://localhost:8080/api/upload" -H "x-password: s3cret" -F "file=@C:\path\to\file.jpg"

Example (Linux / macOS):

curl -X POST "http://localhost:8080/api/upload" \
    -H "x-password: s3cret" \
    -F "file=@/path/to/file.jpg"

HTTP Endpoints

  • POST /api/upload

    • Purpose: Upload a single file (field name: file).
    • Auth: Requires header x-password: <password>.
    • Body: multipart/form-data with a single file part.
    • Response (success): 200 with JSON { URL: "http://<host>/<filename>" }.
    • Response (errors): 400 on missing file, 401 on invalid/missing password.
  • GET /:filename

    • Purpose: Download a previously uploaded file. The server streams the file from disk.
    • Response: 200 with file body and Content-Type derived via the mime-types lookup (falls back to application/octet-stream).
    • Response: 404 if file does not exist.
  • GET /files (or the configured fileListing path)

    • Purpose: Optional file listing page with links and upload timestamps. Disabled when fileListing is false.
    • Response: Simple HTML list of links to the uploaded files and their upload dates`.
  • GET /api/sxcu

    • Purpose: When enableSXCU is true, will return a .sxcu file to be used with ShareX.

Note: All endpoints take the configured baseUrl into account.
This means that every URL, will be prefixed with the baseUrl you have configured. (example: GET /baseUrl/files)


Upload handling and filename strategy

  • Filenames are generated as: ${nanoid(this.filenameLength)}.${mimeSubtype} where mimeSubtype is taken from the uploaded file's mimetype.split("/")[1].
  • A collision safeguard checks whether a file with the generated name already exists and regenerates once if necessary. The probability of collision is extremely low with nanoid.

Security considerations

  • The upload endpoint is protected only by the x-password header; ensure this password is kept secret and that access is restricted by firewall or reverse proxy as needed.
  • Consider running the server behind HTTPS (reverse proxy like Nginx, Caddy, or a cloud load balancer) to protect the password in transit.
  • Be mindful that the server will serve any file present in the savePath; do not use a directory that contains sensitive files.

Troubleshooting & notes

  • The code sets this.#fsPath = join("./", this.savePath). If you encounter path problems on Windows, set savePath to an absolute Windows path (e.g. C:\data\uploads).
  • Ensure the Node process has permission to create and write to savePath.

Documentation notice

This README was produced with the assistance of an AI.