Skip to content

Repository files navigation

Pickly logo

Pickly

A beautiful, private random picker & lucky draw toolkit.
Spin a wheel · Pick a winner · Flip a coin · Roll a die · Split into teams.

TypeScript Vite License CI

No accounts. No tracking. No server.
Your names stay in your browser — everything runs locally, 100% private.

🎡 Live demo: pickly-bw0.pages.dev


✨ What is Pickly?

Pickly is a modern, privacy-first random selection toolkit for classrooms, teams, events, giveaways, meetings, live streams and games. It started as a redesign and extension of the open-source random-name-picker by Ice Lam (MIT) and grew into a complete product with five tools, a full design system, i18n and PWA support.

🎡 Features

Five tools, one shared list

Tool What it does
Wheel A colorful spinning wheel. Pick 1–10 winners with one tap.
Picker A classic slot-machine lucky draw with blur animation.
Coin 3D coin flip — heads or tails.
Dice 3D dice roll with real pip faces.
Teams Split your list into 2–8 balanced teams.

List management

  • Add, edit, delete and reorder entries (drag & drop on desktop, ↑/↓ on touch)
  • Paste lists — one per line; commas and semicolons work too
  • Import (replace or append) and export to a .txt file
  • Shuffle and remove duplicates in one click
  • Sample lists for parties, classes, lunch and games
  • Handles 1,000+ entries, emoji, Chinese and very long names without breaking

Draws & history

  • Multiple winners — pick 1–10 winners per draw
  • Remove winners from the list automatically (toggleable)
  • Undo any draw from the winner dialog or the history panel
  • Full history with relative timestamps; clear anytime

Modern 2026 experience

  • Polished light & dark themes (auto / light / dark)
  • English and 中文 (Simplified Chinese) — switch instantly
  • Confetti, elegant sound effects (Web Audio — no audio files), spring animations, micro-interactions
  • prefers-reduced-motion support plus a manual "reduce animations" setting
  • PWA — installable, works offline, auto-updates
  • Keyboard-friendly: full focus management, Esc closes dialogs, ARIA labels
  • Mobile-first responsive layout — bottom-sheet dialogs, big touch targets

🧱 Tech stack

  • Vite 7 + TypeScript 5 — no framework, dependency-light
  • SCSS design tokens with full dark mode (CSS custom properties)
  • Canvas 2D wheel with cached segment palette, capped tick sounds and a hybrid rAF/timer animation scheduler that survives background throttling
  • Web Animations API for the picker reel
  • Web Audio API for synthesized sound effects
  • canvas-confetti
  • vite-plugin-pwa for offline support
  • Vitest for unit tests
  • Self-hosted variable fonts (Inter + Space Grotesk) — no external requests

🚀 Local development

npm install
npm run dev        # start the dev server
npm run typecheck  # TypeScript checks
npm test           # unit tests
npm run build      # production build → dist/
npm run preview    # preview the production build
npm run icons      # regenerate PWA icons / social card (from logo.svg)

☁️ Deploy to Cloudflare Pages

Pickly is a fully static SPA — it deploys to Cloudflare Pages in minutes.

Option A — Connect the repo (recommended)

  1. Push this repository to GitHub.
  2. In the Cloudflare dashboard, go to Workers & Pages → Create → Pages → Connect to Git.
  3. Choose the repository.
  4. Build settings:
    • Framework preset: Vite
    • Build command: npm run build
    • Build output directory: dist
  5. Save and deploy. public/_redirects provides the SPA fallback automatically.

Option B — Direct upload

npm ci && npm run build
npx wrangler pages deploy dist --project-name=pickly

Option C — GitHub Actions (included)

The repo ships .github/workflows/deploy.yml which builds and publishes on every push to main. Add two repository secrets:

  • CLOUDFLARE_API_TOKEN — an API token with Cloudflare Pages: Edit permission
  • CLOUDFLARE_ACCOUNT_ID — your Cloudflare account ID

wrangler.toml is included with the Pages build settings.

🏗️ Architecture

src/
├── core/          # store (localStorage), i18n, random helpers, audio, confetti
├── locales/       # en + zh dictionaries (typed, test-covered)
├── modes/         # wheel, picker, coin, dice, teams
├── styles/        # design tokens, base, components, panels, modes
└── ui/            # list manager, history, settings, modals, toasts, stepper

Key decisions:

  • No framework — the app is plain TypeScript with a tiny DOM helper, which keeps the bundle at ~21 kB gzipped and the codebase easy to audit.
  • State lives in localStorage (pickly.state.v1) — no backend, no accounts, nothing leaves the browser.
  • i18n is typed — dictionaries share a key union; a test fails if a translation is missing.
  • The wheel is canvas-based — the segment palette is cached, separator strokes are skipped above 200 segments, and tick sounds are capped at 60 per spin so 1,000+ entry wheels stay smooth.
  • Animation is throttle-proof — a setTimeout watchdog backs every requestAnimationFrame frame, so spins complete even in hidden tabs or low-power mode.

🔒 Privacy

Pickly is a static site. There is no analytics, no tracking pixels, no third-party requests at runtime and no server-side storage. Your entry lists, settings and history live only in your browser's localStorage.

📄 License

What changed from the original

The original is a single-screen slot-machine lucky draw in Pug + SCSS + Webpack. Pickly is a full product rebuilt on Vite: five tools (wheel, picker, coin, dice, teams), a complete list manager, winner history with undo, dark mode, EN/中文 localization, PWA/offline support, accessibility hardening and a new design system — while keeping the reel animation, sound engine and shuffle algorithm with attribution.


Made with ♥ for classrooms, teams, events and games.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages