A playful, self-hostable package tracker fork with USPS + UniUni + UPS + Amazon import support and background polling.
Website: https://doprdele.github.io/paqq/
Paqq is a maintained fork focused on self-hosted tracking with scraper-first carrier support.
"I am a strong defender of vibe coding, because, most likely, vibe coding produces better results than you can."
- Paqq-first naming and branding across the stack
- UniUni support end-to-end
- USPS + UniUni + UPS scraping via Playwright/CDP + stealth hardening
- Amazon order import scraper with username/password + optional TOTP
- Asynchronous package add flow:
- package is saved immediately
- modal closes immediately
- tracking fetch runs in background with loading state
- Tabbed settings modal:
- Notifications tab with Apprise URL management + test-notification action
- API keys/credentials tab to store carrier credentials in backend settings (instead of env vars)
- Persistent backend scheduler for self-hosted mode:
- watched targets are persisted
- polling continues until delivery
- delivered targets stop automatic rechecks
- Fork attribution, notice files, and branding policy for redistribution
- Mondial Relay
- Asendia
- Colissimo
- Chronopost
- La Poste
- DHL
- FedEx
- UPS
- USPS
- UniUni
- Amazon (import flow)
- Detailed status/events timeline
- Share/import tracking links
- Dark/light mode
- PWA support
- Local package persistence in browser
- Background fetch + retry for newly added packages
frontend/: static web app (nginx in self-hosted stack)backend/: API + scheduler- Node adapter (
src/node.ts) - Runtime-agnostic fetch adapter (
src/fetch-adapter.ts) for edge/serverless wrappers
- Node adapter (
usps-scraper/: Playwright-based scraper service for USPS/UniUni/UPS + Amazon import
- Docker + Docker Compose
git clone https://github.com/doprdele/paqq.git
cd paqq
docker compose up -d --build- Frontend:
http://localhost:8080 - Backend API:
http://localhost:8787 - Scraper service:
http://localhost:8790
- Frontend calls backend (
/api/*) - Backend calls scraper for USPS/UniUni/UPS/Amazon import
- Scheduler runs in backend and persists state to
/app/data/tracking-scheduler-state.json
PAQQ_API_BASE_URL
PAQQ_TRACKING_SCHEDULER_ENABLED(defaulttrue)PAQQ_TRACKING_SCHEDULER_INTERVAL_MS(default14400000)PAQQ_TRACKING_SCHEDULER_RUN_ON_START(defaulttrue)PAQQ_TRACKING_SCHEDULER_STATE_FILE(default/app/data/tracking-scheduler-state.json)PAQQ_SETTINGS_FILE(default/app/data/paqq-settings.json)PAQQ_APPRISE_PYTHON_BIN(defaultpython3)PAQQ_APPRISE_TIMEOUT_MS(default20000)
-
PAQQ_SCRAPER_STATE_DIR(persistent browser state directory, default auto-detected) -
PAQQ_SCRAPER_PERSIST_SESSION_STATE(defaulttrue) -
AMAZON_PERSIST_SESSION_STATE(carrier override, optional) -
UPS_PERSIST_SESSION_STATE(carrier override, optional) -
USPS_PERSIST_SESSION_STATE(carrier override, optional) -
UNIUNI_PERSIST_SESSION_STATE(carrier override, optional) -
USPS_SCRAPER_URL(backend -> scraper URL, defaulthttp://127.0.0.1:8790) -
USPS_SCRAPER_TOKEN(optional) -
USPS_SCRAPER_TIMEOUT_MS(default300000) -
USPS_SCRAPE_MAX_ATTEMPTS(scraper retries, default10) -
USPS_CDP_WS_ENDPOINT(optional CDP endpoint) -
UNIUNI_SCRAPER_URL(backend -> scraper URL, defaulthttp://127.0.0.1:8790) -
UNIUNI_SCRAPER_TOKEN(optional) -
UNIUNI_SCRAPER_TIMEOUT_MS(default300000) -
UNIUNI_SCRAPE_MAX_ATTEMPTS(scraper retries, default6) -
UNIUNI_CDP_WS_ENDPOINT(optional CDP endpoint) -
UNIUNI_TRACKING_KEY(optional override) -
UPS_SCRAPER_URL(backend -> scraper URL, defaulthttp://127.0.0.1:8790) -
UPS_SCRAPER_TOKEN(optional) -
UPS_SCRAPER_TIMEOUT_MS(default300000) -
UPS_SCRAPE_MAX_ATTEMPTS(scraper retries, default5) -
UPS_CDP_WS_ENDPOINT(optional CDP endpoint) -
AMAZON_SCRAPER_URL(backend -> scraper URL, defaulthttp://127.0.0.1:8790) -
AMAZON_SCRAPER_TOKEN(optional) -
AMAZON_SCRAPER_TIMEOUT_MS(backend timeout, default300000) -
AMAZON_IMPORT_TIMEOUT_MS(scraper timeout, default60000) -
AMAZON_CDP_WS_ENDPOINT(optional CDP endpoint) -
Amazon session cookies/local storage are persisted by default so authenticated sessions can be reused longer between imports.
Paqq is deployable through the companion local-configuration stack behind shared Traefik + OIDC.
From your local-configuration repo:
just paqq-shared-traefik-orbstackCurrent defaults in that stack are already aligned to Paqq:
- repo:
https://github.com/doprdele/paqq.git - host:
paqq.orb.local - API base URL:
https://paqq.orb.local
- Backend + frontend checks use Bun.
- Scraper currently uses Node.js + npm.
cd backend
bun install
bun run start:nodeFor fetch-compatible edge/serverless runtimes, wrap backend with the runtime-agnostic adapter:
import { createFetchRuntimeAdapter } from "./dist/fetch-adapter.js";
const app = createFetchRuntimeAdapter(process.env as Record<string, string | undefined>);
export default app;cd usps-scraper
npm install
npm run startServe frontend/ with any static server and point runtime config at your backend.
For frontend static checks:
cd frontend
bun install
bun run testcd backend
bun run test
bun run test:integration
bun run test:live:uniuni
bun run test:live:upscd usps-scraper
npm test
npm run test:live
npm run test:live:ups
npm run test:live:uniuni
npm run test:live:all-
CI workflow:
.github/workflows/ci.yml- Runs on pull requests and pushes to
main - Executes Bun-based backend build/tests, Node/npm-based scraper build/tests, and Bun-based frontend static checks
- Runs on pull requests and pushes to
-
Release workflow:
.github/workflows/release-calver.yml- Runs after successful
CIonmainpushes - Uses date-based CalVer (
YYYY.M.D, with-rNwhen multiple releases happen the same day) - Automatically updates package versions in:
backend/package.jsonfrontend/package.jsonusps-scraper/package.json+usps-scraper/package-lock.json
- Commits the version update, tags (
v<version>), and publishes a GitHub Release
- Runs after successful
Returns supported carriers and required fields.
Returns normalized tracking payload:
trackingNumbertrackingUrlcarrierstatus { code, description, timestamp, location }estimatedDeliveryevents[]
Imports recent Amazon shipments and invoice artifacts. Supports two-step auth:
- Request 1:
username,password, optionaltotpKey,maxShipments,lookbackDays,archiveDelivered - If
totpKeyis provided, backend attempts automatic TOTP submission when prompted. - If
status === "totp_required": Request 2 withchallengeId+totpCode
GET /api/scheduler/statusGET /api/scheduler/targetsPOST /api/scheduler/watchPOST /api/scheduler/unwatch
GET /api/settings/schemaGET /api/settingsPUT /api/settingsPOST /api/settings/notifications/test
- Original project: Paylicier/Packt
- Fork/project: doprdele/paqq
- Maintainer of this fork: Evan Sarmiento
This fork includes code from Packt by Paylicier, and original notices are preserved.
- Upstream/inherited code: MPL-2.0 (
LICENSE) - Additional distribution in this fork: AGPL-3.0-or-later (
LICENSE-AGPL-3.0.txt) where MPL secondary-license terms allow it - Attribution/provenance:
NOTICE.md - Branding/trademark policy:
TRADEMARKS.md