A private way to rate and share kinks with others

Files
README.md

Kinklist v3 #

Rate kinks privately, then share the result as a short link or an image. No accounts, no backend, no uploads: your list is saved in your browser and never leaves your device unless you share it.

A ground-up rewrite of Goctionni/kinklist-v2. Old v2 links (#<imgurId>) and v2 images still open. The specification is docs/spec.md; deviations and non-obvious choices are in docs/decisions.md. Coding agents: see AGENTS.md.

Features #

  • Rate every kink per role (Self / Partner, Giving / Receiving, …) with an accessible color picker: mouse, touch (44 px targets) or keyboard (arrows, number keys). Comments per kink.
  • Find with diacritic-insensitive search; Unrated dims what's done without hiding it; Has comment; collapse or expand categories.
  • Edit the list: rename inline, add and delete (with undo), reorder by dragging or with the keyboard, edit roles, customize ratings with warnings for colors that colorblind people can't tell apart.
  • Share from ⋯ → Share…:
    • a link (<site>#<data>): the whole list in compressed binary, ~40–180 characters for the default list. It lives in the URL fragment, which browsers never send to servers;
    • a PNG (light or dark, optional comment footnotes) with the list embedded, so the image can be imported again;
    • kinklist.json, or a Markdown summary for chats.
  • Import a link, a PNG or JSON (from the menu, or drop the file anywhere), including v2 data.
  • Autosave on every change, undo/redo (Ctrl/Cmd+Z), light/dark/system theme without flashing, print stylesheet, and no network requests (except fetching the image of an old Imgur link).

Development #

Every tool comes from the Nix flake. You need Nix (with flakes) and direnv.

git clone https://git.hanna.lol/kinklist && cd kinklist
direnv allow   # enters the dev shell, installs git hooks and node_modules
dev            # Vite dev server on http://localhost:5173

Without direnv, use nix develop instead.

Commands (on PATH in the dev shell) #

Command What it does
check Runs every quality gate (below). Run before each commit, and from CI.
fmt Formats all files (Prettier + nixfmt).
dev Vite dev server (extra args are passed to Vite).

Finer-grained pnpm scripts: lint, typecheck, format:check, test, test:coverage, build, budget, e2e.

Quality gates #

check fails on the first failing gate:

  1. @playwright/test version equals nixpkgs' playwright-driver (the browsers come from Nix).
  2. Formatting: Prettier, nixfmt.
  3. Lint: ESLint (type-checked, zero warnings), statix, deadnix.
  4. Types: svelte-check --fail-on-warnings.
  5. Unit + component tests (Vitest) with coverage thresholds (src/lib/** ≥ 95% lines, statements, functions and ≥ 90% branches; src/** ≥ 85% lines).
  6. Production build and the initial-JS budget (≤ 80 kB gzip).
  7. End-to-end tests (Playwright: Chromium, Firefox, WebKit, Pixel 7, iPhone 14) against the build.

For CI: nix flake check and nix develop -c check cover everything; scripts/commit-msg.sh <file> validates a commit message. nix flake check runs the sandboxable subset: js (format, lint, typecheck and unit tests in one derivation), build, nix-lint, pre-commit (Nix hooks) and playwright-version. nix build produces the static site in result/.

After changing dependencies, update pnpmDeps.hash in nix/package.nix: nix build fails with the new hash in its got: line.

Git hooks #

Installed automatically by the dev shell (via git-hooks.nix):

  • pre-commit: Prettier, ESLint, svelte-check, nixfmt, statix, deadnix, and vitest related on staged files.
  • commit-msg: the message must be exactly one line in Conventional Commits format, with no body and no trailers, e.g. feat(ratings): add keyboard shortcuts. See scripts/commit-msg.sh.
  • pre-push: the full check.

Never bypass hooks with --no-verify.

Visual baselines #

tests/e2e/visual.spec.ts compares the main view and exported images (Chromium) against committed screenshots in tests/e2e/__screenshots__/<platform>/. Fonts differ between operating systems, so a platform without baselines skips these tests; create or refresh them deliberately with pnpm exec playwright test tests/e2e/visual.spec.ts --update-snapshots.

Tests #

Layer Location Runner
Unit tests/unit/ Vitest (Node)
Component tests/component/ Vitest + Testing Library
E2E tests/e2e/ Playwright (needs build)
Fixtures tests/fixtures/ shared test data

All functionality needs a test that fails without it.

License #

MIT. Default content and the legacy image codec derive from kinklist-v2 by Goctionni; see LICENSE.