Marketplace architecture
This is a vision document describing how the marketplace + sync stack works when it ships post-1.0. The v1.0 architectural decisions (all-patches-as-references data model,
.stardustshow/bundle format, extension API sandbox) are made with this in mind so we don’t have to break them when it lands.
Skip for v1.0. All of this is v2.0+. Documented here so future planning has the reference and v1.0 architecture stays compatible.
Hard constraints (non-negotiable)
These survive any architectural revision:
- The app works fully without the marketplace. No login required for the app itself. No connectivity required to load shows, load patches, or play.
- Anonymous downloads stay available. Free content can always be fetched without an account.
- No mandatory cloud lock-in. Users own their library data; the marketplace is a distribution channel, not a hostage situation.
- Self-hostable. A team or community can run their own instance of the marketplace server. The protocol is open. AGPL-licensed.
- AGPL-compatible. The marketplace server (and Stardust itself) must remain AGPL-licensable — including paid content distribution. Where a Merchant of Record sits, it sits cleanly.
The three tiers
Tier 1 — Community sharing v1.x bridge
Free, no payments, anonymous-ok. The v1.x bridge step.
- Upload + download shows, patches, rig components, themes, layouts, SFZ packs
- Search / browse / filter / tag
- Ratings + reviews
- Creator pages
- Reporting / moderation tooling
This validates the content-delivery side without the payment plumbing. The full marketplace builds on top of it.
Tier 2 — Marketplace v2.0 (or v1.5)
Tier 1 plus:
- Creator-set pricing
- Payment processing via Merchant of Record (Lemon Squeezy / Polar.sh)
- License verification (downloads tied to purchaser’s account)
- Tax compliance (US sales tax, EU VAT, ROW)
- Creator payouts
- Refunds + disputes
- Verified creator badges
Tier 3 — Cloud sync + collaboration v2.0+
Per-account, CRDT-backed:
- Show backup to cloud
- Library sync across user’s devices
- Multi-MD collaboration on shared shows (CRDT-backed real-time)
- Hot-spare rig sync (LAN-primary, cloud-fallback)
- Multi-keyboardist position sync (LAN-primary)
- Optional: cloud-rendered backing track previews, cloud-stored crash reports
Architectural principles
- Local-first, cloud-optional — every cloud feature additive, never gates
- Self-hostable — open-source server side (AGPL ethos). Community/enterprises can run their own marketplace + sync instance. Stardust hosts the canonical instance.
- Pluggable account system — anonymous downloads (free content), Stardust account (canonical), self-hosted account (federated), future OIDC bring-your-own-provider
- No tracking, no ads, no dark patterns — telemetry opt-in only, analytics aggregate-only, payment data only where required
Merchant of Record
Stardust does not build payment infrastructure from scratch. Payments are processed by a Merchant of Record (MoR) that handles:
- Credit card processing
- Tax compliance (VAT, sales tax, digital services tax)
- Chargebacks and refunds
- Cross-border regulatory compliance
- Anti-fraud
Candidate providers:
- Lemon Squeezy — strong indie-friendly terms, mature API
- Polar.sh — open-source-aligned, growing
- Paddle — bigger, more enterprise, but solid MoR
The MoR holds the payment flow; Stardust holds the content delivery. Sellers get paid by the MoR (minus fees); buyers get a license token from the MoR that the Stardust server redeems against the content.
Recommended tech stack
| Layer | Recommendation | Why |
|---|---|---|
| API | Rust + Axum (or Go + Chi if team grows beyond Rust) | Type safety, perf, single binary, matches engine stack |
| Database | PostgreSQL on Neon (serverless) or self-hosted | Boring, reliable; Neon branching for staging |
| Object storage | Cloudflare R2 | S3-compatible, no egress fees (huge for marketplace downloads), cheap |
| CDN | Cloudflare | Free tier covers a lot; integrates with R2 |
| Real-time messaging | Soketi (Pusher protocol) or raw WebSocket via Axum | Soketi if want client library ecosystem; raw WS if want zero deps |
| Search | Meilisearch (self-hosted) or Postgres full-text | Meilisearch fast + typo-tolerant; PG full-text fine for marketplace v1 |
| Auth | Clerk (managed) or self-hosted Ory Kratos | Clerk = ship fast; Ory = full control + self-hosted |
| Payments | Lemon Squeezy or Polar.sh (Merchant of Record) | MoR handles tax compliance globally — do NOT build yourself |
| Email transactional | Resend or Postmark | Cheap, reliable |
| Crash reporter | GlitchTip (self-hosted Sentry-compatible) | Open source, no per-event fees |
| Site analytics | Plausible (managed or self-hosted) or Umami | Privacy-first, no cookie banner |
| Hosting | Fly.io or Railway for API; Cloudflare Pages for marketing/docs | Cheap, low cognitive overhead, scales reasonably |
See Infrastructure choices for the “why not AWS/GCP” rationale.
Data flow on purchase
Buyer ←──────── Stardust marketplace server ────────→ Seller ↑ ↑ ↑ │ pays │ license + delivery │ uploads + receives payout ↓ ↓ ↓ Merchant of Record (MoR)- Buyer clicks Purchase in the marketplace UI inside Pit
- Pit opens the MoR’s checkout (in-app webview or external browser)
- Buyer pays the MoR
- MoR posts a success webhook to the Stardust marketplace server
- Stardust server issues a license token to the buyer’s account
- Pit fetches the asset, validates the license, installs to the global library
License model
Each paid purchase produces a license token held in the user’s Stardust account. The token authorizes:
- Download of the asset
- Use of the asset across all the user’s installs
- Receipt of updates (within the subscription window if subscription-based)
License tokens are stored in the user’s Stardust account and cached locally so the app keeps working without network access. The marketplace server only needs to be reachable for purchase, install, and update — not for running content that’s already installed.
What’s sold
The marketplace is a distribution surface for library entries (per Patch library) and extensions:
| Asset | Free | Paid |
|---|---|---|
| Patches — single library entries | ✓ | ✓ |
| Patch packs — curated collections | ✓ | ✓ |
Show templates — full .stardustshow bundles for common works | ✓ | ✓ |
| Click tracks — for public-domain works | ✓ | ✓ |
| SFZ packs — sample-based instruments via v0.14.0’s native SFZ player | ✓ | ✓ |
| Extensions — TS / WASM bundles | ✓ | ✓ |
| Plugin bundles — recipes that install groups of free plugins | ✓ | rarely |
Paid content can be one-time-purchase or subscription (typically annual, for content that gets updated like maintained click tracks for active touring productions).
Sync architecture — CRDT (Automerge)
Three patterns considered:
- Last-write-wins (LWW) — simple; data loss on conflict
- Operational Transform (OT) — server resolves edits; needs always-on server
- CRDTs (Automerge, Yjs) — edits merge mathematically; works offline + P2P + via server
Recommendation: CRDTs (Automerge).
Reasons:
- Local-first principle satisfied — works fully offline, sync when reconnected
- Multi-device for one user — same show on laptop + studio Mac sync automatically
- Multi-user collaboration — two MDs editing the same show resolve cleanly
- Hot-spare rig — same sync protocol, just over LAN
- Multi-keyboardist position sync — same protocol, ephemeral state
- Mature — Automerge 2 production-ready
- Open source — MIT/Apache, no licensing concerns
The show file format is amenable to CRDTs: node-based graph + reference-based patches = exactly the shape CRDTs handle well. Migration from “save whole document” to “CRDT-backed document with change history” is non-trivial but pays off across many features.
Self-hosted instances
The marketplace server is open source under AGPL. A theatre company, conservatory, or content distributor can run their own instance — useful for:
- Private content (commissioned shows, in-house patch libraries)
- Regional content (a country-specific show ecosystem)
- Pre-public-launch testing
Self-hosted instances can federate with the canonical Stardust marketplace (v2.0+) so content is searchable across instances; or stay private.
Phasing
| Phase | Versions | What ships |
|---|---|---|
| v1.0 (no cloud) | through v1.0.0 | Pit fully local. No account. No marketplace. No sync. |
| Bridge | v1.1 – v1.3 | Anonymous share hub: upload as public URL, download with link. No accounts, no payments. Cloudflare-only stack. Foundation before commerce. |
| Marketplace v1 | v1.5 (or v2.0) | Tier 2: full marketplace with accounts, paid content, Lemon Squeezy MoR, creator pages. ~3–4 months dedicated. |
| Sync + collaboration | v2.0 (or v2.x) | Tier 3: CRDT migration, cloud backup, multi-device sync, real-time collab, hot-spare LAN, multi-keyboardist LAN. ~6 months. |
| Federation / self-host | v2.x | Documented self-hosted marketplace server; federated identity. marketplace.stardust.org canonical; others run their own. |
Rough cost projection
Canonical marketplace instance scaled to ~10k users / 1k creators / 100k downloads per month:
| Service | Cost |
|---|---|
| Fly.io (API + workers) | $30–80 |
| Neon PostgreSQL | $20–50 |
| Cloudflare R2 (storage + CDN) | $20–100 |
| Clerk auth (10k MAU) | $0–25 |
| Lemon Squeezy | 5% + $0.50 per transaction (no fixed) |
| Plausible analytics | $9 |
| GlitchTip crash | $0 self-hosted |
| Total fixed | ~$80–270/month |
| Plus transaction fees | Variable |
Affordable for indie. Lemon Squeezy MoR fee is the biggest cost but covers global tax compliance.
ADRs needed when marketplace work starts
- ADR: Marketplace tech stack + Merchant of Record selection
- ADR: CRDT vs OT vs LWW for sync
- ADR: User accounts + identity (managed vs self-hosted, federation)
- ADR: Self-hosting + federation model
- ADR: Content moderation policy + enforcement tooling
What to do now (before any work)
- Don’t build any of it for v1.0. Pit shipping local-first is right; cloud after.
- Reserve domains:
marketplace.stardust.org,accounts.stardust.org,api.stardust.org - Add stubs to v2.0+ backlog (done in the roadmap)
- Design data model with sync in mind — all-patches-as-references already helps; CRDT-friendliness is a free side-effect of structured normalized data
- Be careful about file format — the
.stardustshow/bundle format (folder) is more CRDT-friendly than monolithic JSON (individual files sync independently) - Keep an ADR drafts folder for future-you
What NOT to do
Don’t build a Stardust account requirement into v1.0 “just in case.” Local-first means local-first. Adding cloud features later doesn’t need account migration — the local install just starts offering optional account features.
What this is NOT
- Not an exclusivity deal. Sellers can list the same content elsewhere.
- Not a DRM system. Content is downloaded as files; copying is technically possible. Licensing is enforceable but not bulletproof — and we don’t pretend otherwise.
- Not a curated-only walled garden. Anyone can publish. Curation surfaces (editor’s picks, featured collections) layer on top.
- Not an enterprise CMS. It’s a marketplace, not a content management platform.
Related pages
- Patch library — the data model the marketplace consumes
- Community sharing — the v1.x bridge
- Marketplace — the consumer-facing surface
- Infrastructure choices
- Extension API — extensions are marketplace assets too