Skip to content

pessini/litedrop

Repository files navigation

litedrop

litedrop

Share markdown and HTML files through links with optional expiration, passwords, and view limits. litedrop is CLI-first, single-user, and self-hosted.

It runs as one Node process: the API, public share pages, and dashboard are served together on port 8080. By default it uses embedded SQLite and local disk storage, with optional S3, R2, or Azure blob storage.

Quick Start

Run locally with Docker and no domain:

docker run --rm -p 8080:8080 \
  -e ADMIN_PASSWORD=change-me-please \
  -e LITEDROP_TOKEN=dev-token-change-me-please \
  -e ALLOW_SAME_ORIGIN_CONTENT=true \
  -v litedrop-db:/app/apps/backend/.data \
  -v litedrop-blobs:/app/apps/backend/.storage \
  pessini/litedrop:latest

Open http://localhost:8080. If you map a different host port, set APP_BASE_URL, for example APP_BASE_URL=http://localhost:3000.

Or run locally from source:

npm install
LITEDROP_TOKEN=dev-token-change-me-please \
  ADMIN_PASSWORD=change-me-please \
  npm run -w @litedrop/backend dev

Open http://localhost:8080, then use the CLI with the same token:

brew tap pessini/tap
brew install litedrop
litedrop login --url http://localhost:8080
litedrop push README.md

Using the hosted service at litedrop.dev? Skip the local server and just run litedrop login (no --url needed) with the token from your account — the CLI targets the hosted service by default.

For production, pull the published container and put a TLS proxy in front:

docker run -p 8080:8080 \
  -e ADMIN_PASSWORD=change-me-please \
  -e LITEDROP_TOKEN=$(openssl rand -hex 32) \
  -e APP_BASE_URL=https://app.example.com \
  -e PUBLIC_SHARE_BASE_URL=https://s.example.com \
  -e CONTENT_BASE_URL=https://content.example.com \
  -v litedrop-db:/app/apps/backend/.data \
  -v litedrop-blobs:/app/apps/backend/.storage \
  pessini/litedrop:latest

See SELF_HOSTING.md for DNS, TLS, volumes, backups, and all environment variables.

How It Works

  • Auth: ADMIN_PASSWORD logs into the dashboard. LITEDROP_TOKEN is the bearer token used by the CLI and API clients. There are no accounts, signup flows, or auth database tables.
  • Shares: anyone with a share link can view it. Only an authenticated user can create, list, or revoke shares.
  • Link controls: each share can expire, require a password, or stop after a maximum number of views. Expired, revoked, and fully consumed links all return the same 404.
  • HTML safety: markdown is sanitized on the app origin. Uploaded HTML is served from an isolated content origin into a sandboxed iframe under a strict CSP. Single-host deployments can opt out with ALLOW_SAME_ORIGIN_CONTENT=true.
  • Storage: local disk is the default. Set STORAGE_PROVIDER to s3, r2, or azure when you want object storage instead.

CLI

brew tap pessini/tap
brew install litedrop

litedrop login --url http://localhost:8080
litedrop push report.html
cat NOTES.md | litedrop push - --name NOTES.md
litedrop push secret.md --expires 24h --max-views 3
litedrop ls            # table; --json for machine output
litedrop open <id|slug>
litedrop revoke <id|slug>
litedrop logout

If the machine running the CLI does not have Node.js, install the standalone binary from GitHub Releases:

curl -fsSL https://raw.githubusercontent.com/pessini/litedrop/main/cli/scripts/install.sh | sh

You can also install the CLI with npm when Node.js is already available:

npm install -g @litedrop/cli

Config is stored at ~/.config/litedrop/config.json with 0600 permissions. litedrop push prints only the share URL on stdout, so scripts can capture it: URL=$(litedrop push report.html).

API

TOKEN=... # your LITEDROP_TOKEN

# Upload markdown or HTML.
curl -s -X POST "localhost:8080/api/shares?name=NOTES.md" \
  -H "Authorization: Bearer $TOKEN" \
  --data-binary @NOTES.md

# View rendered content or raw bytes.
curl localhost:8080/<slug>
curl localhost:8080/<slug>/raw
curl -H "Accept: text/plain" localhost:8080/<slug>

# Manage shares.
curl localhost:8080/api/shares -H "Authorization: Bearer $TOKEN"
curl -X DELETE localhost:8080/api/shares/<id> -H "Authorization: Bearer $TOKEN"

JSON uploads are also supported:

curl -s -X POST localhost:8080/api/shares \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"name":"hi.md","content":"# Hello"}'

Optional controls:

Control Raw upload JSON upload Notes
Expiration ?expires=24h {"expires":"24h"} Supports 1h, 24h, 7d, 30d, never, <n>h, <n>d, or ISO-8601. Default is 7d; past timestamps are rejected.
Password X-Litedrop-Share-Password {"password":"..."} Stored as a scrypt hash; never echoed. Browsers unlock with a signed slug cookie. Agents can send X-Litedrop-Password. Wrong passwords do not cost a view.
Max views ?max_views=3 {"max_views":3} Burn-after-read; increments are atomic.

Uploads are limited to markdown and HTML extensions (.md, .markdown, .html, .htm), UTF-8 text, and 5 MB.

Development

litedrop/
|-- apps/
|   |-- backend/         # Hono + Drizzle API and SSR public pages
|   `-- dashboard/       # Vue 3 dashboard SPA
|-- packages/
|   |-- core/            # @pessini/litedrop-core
|   `-- api-types/       # @litedrop/api-types
`-- cli/                 # Node/TypeScript CLI

Stack:

  • Backend: Hono, Drizzle ORM, embedded SQLite, Zod, markdown-it, sanitize-html, dependency-free S3/R2 SigV4 signing, and standalone Azure Shared-Key signing.
  • Dashboard: Vue 3 and Vite.
  • CLI: TypeScript and commander.
  • Tooling: TypeScript 6, Biome, native Node.js TypeScript stripping, node:test, and npm workspaces.

Common scripts:

Script Purpose
npm run -w @litedrop/backend dev Run the backend dev server with node --watch.
npm run build Build all workspaces.
npm run typecheck Type-check without emitting.
npm run -w @litedrop/backend db:migrate Apply committed SQLite migrations.
npm run -w @litedrop/cli build Build the CLI.
npm run -w @litedrop/cli compile:local Build a local standalone CLI binary.

SQLite migrations run automatically at backend boot, so production does not need a separate migration command.

About

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors