Casset Apps
Casset Apps are interactive experiences that live inside an artist profile.
Build a profile room, interactive discography, visualizer, game, or collector experience. Start locally with a downloadable project and sample Casset data—no credentials required.
The local SDK and starters work today. Production Casset Apps are reviewed and code-owned by Casset; third-party submission is not open.
curl -LO https://casset.fm/downloads/casset-apps/casset-minimal-profile-app-v0.2.0-alpha.0.zip
unzip casset-minimal-profile-app-v0.2.0-alpha.0.zip
cd casset-minimal-profile-app
pnpm install
pnpm test
pnpm devChoose your path
Start with the thing you want to build.
Five-minute start
Build your first app.
Choose a Profile or Track starter and enter its root folder.
Install dependencies, start the local app, and explore its sample states.
Change the manifest and interface, then run the included tests and build.
What you can build
Choose where your experience runs.
How it works
Use the local SDK included with every starter.
@casset/appsvendored host contracttypescriptcontract checkingvitelocal buildvitestfixture and state testsreactReact starter onlyManifest
- Identity and version
- Profile or Track context
- Placements and permissions
- Track kinds when applicable
Context
- Short-lived launch lifecycle
- Minimized public data
- Explicit Profile data states
- URL-free Track resource references
Host
- Capability detection
- Profile-only PLAY_TRACK request
- Lifecycle subscriptions
- Fail-closed close and invalid requests
import {
hasCassetPermission,
hostSupports,
isCassetDataReady,
type CassetAppHost,
} from "@casset/apps"
export async function playFirstTrack(host: CassetAppHost) {
const { context } = host.getSnapshot()
if (context.kind !== "PROFILE_SURFACE") return
if (!isCassetDataReady(context.catalog)) return
if (!hasCassetPermission(context, "playback.control")) return
if (!hostSupports(host, "PROFILE_PLAY_TRACK")) return
const track = context.catalog.data.tracks[0]
if (track) await host.request({ type: "PLAY_TRACK", trackId: track.id })
}{
"schema": "casset.app-manifest.v1",
"id": "studio.afterglow-room",
"slug": "afterglow-room",
"name": "Afterglow Room",
"shortDescription": "A quiet release room inside the Profile World.",
"description": "Stages an approved release and requests playback through Casset.",
"developer": { "name": "Your studio" },
"version": "0.1.0",
"icon": "/icon.svg",
"screenshots": [],
"category": "IDENTITY",
"context": "PROFILE_SURFACE",
"placements": ["ARTIST_APP_ROUTE"],
"permissions": [
"artist.profile.read",
"artist.theme.read",
"catalog.tracks.read",
"playback.read",
"playback.control"
],
"supportedFanAccess": ["FREE"],
"compatibility": { "mobile": true, "desktop": true, "pwa": true },
"trackApplicability": null
}@casset/apps is not published to npm. The starter ZIPs include the exact pre-release source and install it through a local file: dependency, so the imports above are real without implying an open package or marketplace.
Apps receive
- Approved artist, theme, Catalog, and release data
- Explicit loading, empty, denied, and unavailable states
- Track time and lifecycle updates supplied by Casset
- Checks for the requests the current host supports
Casset retains
- Installation, entitlement, and launch authority
- The global player and canonical audio clock
- Routes, runtime dispatch, and raw media delivery
- Disablement, exit, and production integration
Agent-ready Markdown
Give Codex or Claude a focused build brief.
AGENTS.md
- Canonical Casset doctrine
- Files the agent may change
- Runtime authority rules
- Required validation commands
CLAUDE.md
- The same host boundary
- Sparse-state expectations
- Mobile and reduced-motion rules
- No second player or private data
PROMPT.md
- A reusable task brief
- Creative intent and interaction
- Acceptance criteria
- Test and build handoff
# Build brief for Codex or Claude Code
## Objective
Turn the artist's active release into a quiet afterglow room inside
the existing Profile World.
## Use
- The vendored `@casset/apps` package
- The provided fixture and host lifecycle
- The starter's existing test and build commands
## Preserve
- Casset owns artist identity, authorization, playback, and exit
- Request playback through the host; never mount an `<audio>` element
- Handle loading, empty, unavailable, and permission-denied states
- Keep the interface calm, mobile-first, and artist-specific
## Verify
- `pnpm test`
- `pnpm build`Runnable projects
Choose the smallest starter that fits.
Availability
What works today—and what does not.
Use now
- Repository-local @casset/apps
- Three standalone starter ZIPs
- Strict parsers and fixtures
- Trusted production Track contract
Casset only
- Registry and runtime keys
- Installation and entitlement truth
- Playback stores and MediaFooter
- Raw media and server authorization
Not shipped
- npm publication
- Public submit or review API
- Arbitrary bundle isolation
- Live revocation and resource delivery