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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@package-uploader/ui

v1.1.10

Published

React UI for uploading and browsing courses on LMS platforms

Readme

@package-uploader/ui

React UI for uploading and browsing courses on LMS platforms. Includes drag-and-drop upload, folder navigation, and course launching.

Features

  • Drag-and-drop upload: Upload multiple course ZIPs at once
  • Folder browser: Navigate folder hierarchy, select destination
  • Document browser: Search and filter uploaded courses
  • Course launcher: One-click launch via shared links
  • Server included: Express server serves UI on single port

Installation

npm install @package-uploader/ui

Quick Start

Option 1: Run with Server (Recommended)

The package includes a complete server/UI setup:

# Clone the repository
git clone <repo>
cd package.uploader

# Install all dependencies
npm install
cd server && npm install && cd ..
cd ui && npm install && cd ..

# Configure environment
cp server/.env.example server/.env
# Edit server/.env with your LMS credentials

# Build and run
cd server
npm run build
npm start

Open http://localhost:3002 in your browser.

Option 2: Development Mode

# Terminal 1: Run server
cd server
npm run dev

# Terminal 2: Run UI (with hot reload)
cd ui
npm run dev

UI runs on http://localhost:5173, API on http://localhost:3002.

Server Configuration

Create server/.env:

# LMS API Configuration
UPLOADER_BASE_URL=https://your-lms.example.com
UPLOADER_API_KEY=your-api-key

# Patch-Adams Integration (optional)
PATCH_ADAMS_ENABLED=true
PATCH_ADAMS_DOMAIN=https://cdn.example.com/rise-overrides

# Server Port
PORT=3002

API Endpoints

The server exposes these endpoints:

Folders

GET /api/folders              # List all folders
GET /api/folders/:id          # Get folder by ID
GET /api/folders/:id/subfolders  # List subfolders

Documents

GET /api/documents            # List all documents
GET /api/documents?folderId=X # List documents in folder
GET /api/documents/:id        # Get document by ID
GET /api/documents/:id/launch # Get launch URL

Upload

POST /api/upload              # Upload new course
  - file: ZIP file (multipart)
  - folderId: Target folder ID
  - title: Document title (optional)
  - description: Description (optional)

POST /api/upload/version      # Upload new version
  - file: ZIP file (multipart)
  - documentId: Target document ID
  - note: Version note (optional)

Health Check

GET /api/health               # Server status

UI Pages

Upload Page (/)

  • Drag-and-drop zone for ZIP files
  • Folder tree for destination selection
  • Upload queue with status tracking
  • Batch upload support

Browse Page (/browse)

  • Document grid view
  • Search by name
  • Filter by folder
  • One-click course launch
  • View document details

Components

DropZone

import DropZone from './components/DropZone';

<DropZone onFilesAdded={(files) => handleFiles(files)} />

FolderSelect

import FolderSelect from './components/FolderSelect';

<FolderSelect
  selectedId={selectedFolderId}
  onSelect={(id) => setSelectedFolderId(id)}
/>

FileList

import FileList from './components/FileList';

<FileList
  files={uploadQueue}
  onRemove={(index) => removeFile(index)}
  onRetry={(index) => retryUpload(index)}
/>

Deployment

Docker

# Build stage
FROM node:18-alpine AS builder
WORKDIR /app

# Install dependencies
COPY package*.json ./
COPY server/package*.json ./server/
COPY ui/package*.json ./ui/
RUN npm install && cd server && npm install && cd ../ui && npm install

# Copy source
COPY . .

# Build
RUN cd ui && npm run build
RUN cd server && npm run build

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/server/dist ./dist
COPY --from=builder /app/server/package*.json ./
COPY --from=builder /app/ui/dist ./ui/dist
RUN npm ci --production
EXPOSE 3002
CMD ["node", "dist/index.js"]

Docker Compose

version: '3.8'
services:
  package-uploader:
    build: .
    ports:
      - "3002:3002"
    environment:
      - UPLOADER_BASE_URL=https://your-lms.example.com
      - UPLOADER_API_KEY=your-api-key
      - PATCH_ADAMS_ENABLED=true
      - PATCH_ADAMS_DOMAIN=https://cdn.example.com/rise-overrides

Manual Deployment

# Build UI
cd ui && npm run build

# Build Server
cd server && npm run build

# The server will serve UI from ../ui/dist
# Deploy server/dist + ui/dist together

Integration with CI/CD

GitHub Actions

name: Build and Deploy
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: |
          npm install
          cd server && npm install
          cd ../ui && npm install

      - name: Build
        run: |
          cd ui && npm run build
          cd ../server && npm run build

      - name: Deploy
        run: # Your deployment steps

Project Structure

package.uploader/
├── package.json          # @package-uploader/core (npm package)
├── src/                  # Core library source
├── server/
│   ├── package.json      # Server package (private)
│   ├── src/index.ts      # Express server
│   └── .env.example      # Environment template
└── ui/
    ├── package.json      # @package-uploader/ui (npm package)
    ├── src/
    │   ├── App.tsx
    │   ├── pages/
    │   │   ├── UploadPage.tsx
    │   │   └── BrowsePage.tsx
    │   └── components/
    │       ├── DropZone.tsx
    │       ├── FileList.tsx
    │       └── FolderSelect.tsx
    └── index.html

Dependencies

UI

  • React 18+
  • React Router DOM
  • react-dropzone

Server

  • Express
  • Multer (file uploads)
  • @package-uploader/core
  • dotenv

License

MIT