Repository navigation
Description
Friction removal — multi-phase plan to eliminate first-run friction
Context
jspod is the user-facing front door of the JavaScript Solid Server ecosystem — the "npx and you're running" path that turns the powerful-but-expert-flagged JSS substrate into a zero-friction first experience. This issue inventories the friction that still exists between discovery and working pod, and breaks the fixes into phases that can be executed independently.
The diagnosis came from walking the actual new-user path through the JSS + jspod README/code as of 2026-05-15 and identifying the gaps a first-time visitor would hit.
Problem statement
The intended new-user funnel is:
land on a JSS-related repo → discover jspod → npx jspod → browser opens → register → working pod
The actual funnel today breaks in several places:
- Discovery gap: a user landing on the canonical JSS repo (
JavaScriptSolidServer/JavaScriptSolidServer) is told to donpm install -g javascript-solid-server && jss start— which produces a bare headless server. They don't learn thatnpx jspodexists. - Internal inconsistency:
jspod's README documentslocalhost:3000whilebin/jspod.jsdefaults to5444. The help banner refers to the binary asjssd(wrong name). New users following the README hit a dead URL. - No demo experience by default: even via
npx jspod, the data browser UI (mashlib) is not enabled by default. The user openshttp://localhost:PORTand sees minimal output rather than a working data browser. - No auto-open: the user has to manually copy the URL from terminal to browser. This is the cheapest 5-second-of-delight intervention and we're not making it.
- Empty pod after registration: post-passkey-registration, the pod is empty. The user thinks "now what?" — there is no guided first-action.
- No visual proof: the README has no screenshot, GIF, or video. Visual proof is the fastest trust signal for a substrate product and we're not providing it.
- No measurement: we can't tell whether any intervention works because there's no baseline metric for adoption velocity.
Goals
- New user goes from "saw jspod" to "working pod with visible UI" in under 60 seconds
- Every step is opinionated by default with overrides available for advanced users
- Adoption velocity becomes measurable so future interventions can be evaluated
- All fixes preserve the "Simple over complex. Defaults over configuration. Works over features." philosophy already stated in the jspod README
Non-goals (out of scope for this issue)
- Adding new JSS features
- Restructuring the multi-user model
- Production-deployment hardening (covered separately)
- Federation / ActivityPub flow (not on the first-run critical path)
- iOS / mobile-app distribution (separate channel)
Phase 1 — Fix jspod internal inconsistencies (quick wins, ~1 hour)
Why: a user following the jspod README literally hits a dead URL because of the port mismatch. Fix the basics before anything else.
Tasks
- Resolve port conflict: README documents
:3000,bin/jspod.jsdefaults to5444. Pick one (5444is more memorable + lower collision with common dev servers like Next.js / Rails). Update all references inREADME.md,bin/jspod.js, andindex.js. - Fix help banner:
bin/jspod.jshelp block saysjssdinstead ofjspod. Replace alljssdreferences withjspod. - Verify CLI examples in README match actual CLI behaviour:
--port,--host,--root,--multiuser,--no-auth,--help. - Add
--versionflag if not present.
Acceptance criteria
npx jspod --helpoutput matches what the README documents- The URL printed at startup matches the URL the README tells users to open
grep -i 'jssd' bin/returns nothing
Files to touch
bin/jspod.jsREADME.mdindex.js
Phase 2 — Enable demo experience by default (highest-leverage change)
Why: npx jspod currently spawns JSS without --mashlib-cdn or --idp enabled (afaict from defaults inspection). The user opens the browser and sees minimal output rather than a data browser UI. This is the "I see what this does" moment we're failing to deliver.
Tasks
- Audit which JSS flags
jspodcurrently passes through. Document them. - Add the following to jspod's default flag set:
--idp— built-in Identity Provider (so passkey registration works)--mashlib-cdn— data browser UI (so the user sees something at/)--conneg— content negotiation (already enabled per README; verify)--notifications— WebSocket notifications (already enabled per README; verify)
- Add
--minimalflag for advanced users who want the bare-headless mode (this is the inversion: minimal becomes opt-in, demo becomes default). - Verify: after
npx jspod, openinghttp://localhost:5444in a fresh browser shows a Mashlib data browser UI (not a JSON response).
Acceptance criteria
- Fresh
npx jspod+ browser visit tolocalhost:5444shows a recognizable data browser interface within 5 seconds npx jspod --minimalproduces the current bare-server behavior for users who want it- No regression in startup time beyond what mashlib-cdn legitimately requires
Files to touch
index.js(or wherever the JSS spawn args are constructed)bin/jspod.js(for the--minimalflag parsing)README.md(document the new defaults +--minimalopt-out)
Phase 3 — Auto-open browser on first start
Why: cheapest possible delight intervention. The user runs one command and the next thing they see is their working pod in their browser. No copy-paste required.
Tasks
- Add
openoropeneras a small dependency (or shell out toxdg-open/open/startper platform). Prefer zero-dep platform detection where feasible. - On first start, open
http://${host === '0.0.0.0' ? 'localhost' : host}:${port}in the user's default browser. - Add
--no-openflag for CI / server / agent-only environments. - Detect environment (CI, ssh, non-interactive) and skip auto-open in those cases by default.
Acceptance criteria
npx jspodon a fresh laptop opens the browser to the working pod within 3 seconds of the server being readynpx jspod --no-openskips auto-opennpx jspodin CI / ssh / non-TTY context skips auto-open without error
Files to touch
index.jsbin/jspod.jspackage.json(if addingopendependency)README.md
Phase 4 — First-touch success state
Why: after passkey registration, the pod is empty. The user thinks "now what?". We can pre-populate with example content and add a brief guided tour so the next 30 seconds feel meaningful instead of empty.
Tasks
- On first pod creation, seed the pod with:
- A
/profile/card$.ttl(or.jsonld) with the user's WebID and basic profile slots - A
/public/container with awelcome.mdorwelcome.jsonldcontaining a "you have a pod, here's what you can do" guide - A
/private/container with appropriate ACL - A
/inbox/container for LDN notifications
- A
- Make the welcome content actually useful — not just placeholders. Include:
- Links to JSS docs
- List of 3-5 Solid apps the user can connect with
- "What is a pod?" link
- Show a post-registration toast or banner: "Your pod is ready. Here's how to use it →" with a link to the welcome resource.
- Add
--no-seedflag for users who want a truly empty pod.
Acceptance criteria
- After
npx jspod+ registration, the data browser shows a non-empty pod with at least 3 useful resources - The welcome resource explains the next 3 things the user can do
--no-seedproduces an empty pod for users who want one
Files to touch
index.js(or newlib/seed.js)- Possibly a
templates/directory with the seed content README.md
Phase 5 — Visual / discovery assets
Why: visual proof is the fastest trust signal. A 30-second GIF of npx jspod → browser opens → registration → working pod is worth more than 1000 README words.
Tasks
- Record a 30-60 second GIF / MP4 of the full first-run experience:
- Terminal:
npx jspod - Browser opens automatically
- Passkey registration (or screenshot if hardware-dependent)
- Working data browser with seeded content
- Terminal:
- Add the GIF to the top of the jspod README, above the install commands.
- Add a screenshot of the data browser UI somewhere visible.
- Write a one-line "what jspod is for" statement that goes immediately under the title. Current: "JavaScript Solid Server Daemon - Just works, batteries included". Consider: "Your personal Solid pod in one command. No install, no config, no friction."
- Add a "Try without installing" link to a hosted demo (e.g.,
solid.socialif it serves jspod-equivalent UX, or set updemo.jspod.dev/try.jspod.dev).
Acceptance criteria
- A visitor to the README sees a working GIF within the first viewport
- Screenshot of the data browser is embedded
- Hosted try-it link is present (even if it points to
solid.socialas an interim)
Files to touch
README.md- New
docs/assets/directory for the GIF / screenshot - Possibly a deployment for a try-it instance (separate ticket)
Phase 6 — Cross-repo: surface jspod from the JSS README
Why: most JSS-curious users land on github.com/JavaScriptSolidServer/JavaScriptSolidServer, not on jspod. The JSS README currently leads with npm install -g javascript-solid-server which is the expert / server-operator path. We need to make the casual / first-time path visible at the top.
This is cross-repo work; needs a coordinated PR against the JSS repo.
Tasks
- Open PR against
JavaScriptSolidServer/JavaScriptSolidServerto update the Quick Start section:- Easiest path (recommended for new users):
npx jspod - Advanced / server operators: the current
npm install -g javascript-solid-serverflow
- Easiest path (recommended for new users):
- Add a "What's the difference?" callout: jspod is the opinionated front door; JSS is the substrate.
- Link from JSS README → jspod, and vice versa.
- Update JSS architecture diagram caption (if applicable) to show jspod as the consumer-facing layer.
Acceptance criteria
- A new visitor to the JSS repo sees
npx jspodas the headline install path within the first viewport - The path from JSS README to jspod is one click
- The path from jspod README to JSS (for advanced users) is one click
Files to touch
JavaScriptSolidServer/JavaScriptSolidServer/README.md(cross-repo PR)JavaScriptSolidServer/jspod/README.md(link back)
Phase 7 — Baseline measurement (can run in parallel with Phases 1-6)
Why: we can't tell whether the friction removal is working without measurement. This phase establishes the north-star metric and lightweight telemetry so future interventions can be evaluated objectively.
Tasks
- Decide the north-star metric. Candidates:
- npm downloads per week (free, lagging, but real signal)
- GitHub stars (vanity; deprioritize)
- Unique active jspod instances (requires opt-in telemetry)
- Issues opened by new users (proxy for engagement)
- Discussion posts from new users
- If implementing opt-in telemetry: anonymous, opt-in via prompt on first run, with crystal-clear what is sent / what is not messaging. Default: opt-out.
- Set up a simple dashboard (Grafana / custom / Plausible / etc.) so the metric is visible at a glance.
- Document the metric and review cadence (weekly).
Acceptance criteria
- One north-star metric is defined and being tracked
- Dashboard / spreadsheet exists where the metric is visible
- Documentation explains what is and isn't measured
Files to touch
- New
TELEMETRY.mddocument - Possibly
index.jsfor opt-in telemetry - README disclosure block
Execution notes for whoever picks this up
- Phase order matters but isn't strict. Phases 1, 2, 3 should be done in order — they compound. Phase 6 (cross-repo) and Phase 7 (measurement) can run in parallel with the others. Phases 4 and 5 can be reordered if visual assets are easier to produce first.
- Ship small. Each phase should land as its own PR. Don't bundle.
- Test on a clean machine. The whole point is the new-user experience. Test as if you've never seen jspod. Use a VM or a co-worker if needed.
- Preserve the philosophy. "Simple over complex. Defaults over configuration. Works over features." — if any change makes the README longer or the CLI more complex, reconsider it.
- Cross-link generously. Reference this issue from every PR that resolves a phase, so progress is visible.
Definition of done (overall)
A first-time visitor who types npx jspod ends up looking at a working data browser UI in their default web browser, with their freshly-registered passkey-authenticated WebID, viewing a non-empty pod, in under 60 seconds, with no further commands typed. The terminal output is beautiful and unambiguous about what to do next.
When that's true, the discovery → first-pod funnel is structurally sound, and we can start optimizing later stages (retention, network effect, killer-app integrations) with a known-good first-touch.
References
- jspod repo: https://github.com/JavaScriptSolidServer/jspod
- JSS repo: https://github.com/JavaScriptSolidServer/JavaScriptSolidServer
- jspod README (current): see repo root
- JSS README (current): see repo root
- Solid project: https://solidproject.org
Activity
fix: resolve port/name inconsistencies and add --version (#1 phase 1) (…
fix: address Copilot review on PR #4
Phase 3: auto-open browser on first start (#4)
fix: address Copilot review on PR #7
fix: address Copilot review 2 on PR #7
fix: address Copilot review 3 on PR #7
fix: address Copilot review 4 on PR #7
fix: address Copilot review 5 on PR #7
Phase 2: enable IDP, seed me/me, localhost-only by default (#7)
feat: ship a 200-byte data browser, replace mashlib bundle by default (…
fix: pretty-print + visible palette + single-file data browser (#9)
feat: seed /public/links.jsonld on first run (#13)
feat: ship a tiny sign-in app at /signin.html (#15)
feat: ship /account.html — post-sign-in dashboard (#16)
feat: change-password form on /account.html (rung-1 → rung-2 climb) (#17
feat: warn on /account.html when password is still default (#18)
feat: welcome.html is auth-aware (completes MVP) (#19)
feat: bundle Pilot as a self-hosted Solid app under /public/apps/pilo…
feat: ship /docs.html — operator-facing reference (#21)
feat: nav header on data-browser pages (Up / Home / Account / Docs) (#23
melvincarvalho commentedon May 16, 2026
Progress audit as of jspod 0.0.25:
/public/links.jsonldshipped (PR #13); profile / inbox / private seed not addressedAdjacent wins along the way (not in original phases but shipped):
/signin.htmlusing solid-oidc (PR feat: tiny sign-in app at /signin.html #15)/account.htmlwith rung-1 → rung-2 climb form (PR feat: /account.html post-sign-in dashboard #16, feat: change-password form on /account.html (climb to rung 2) #17, feat: warn on /account.html when password is still default #18)/public/apps/pilot/— first self-hosted Solid app (PR feat: bundle Pilot at /public/apps/pilot/ (self-hosted Solid app) #20)/docs.html(PR feat: docs page at /docs.html #21)Upstream-blocked items now filed against JSS:
Leaving this open until Phases 4-7 land.
feat: bump jss to 0.0.195 and enable --git by default (#27)