Template React 1 page MIT

Suna Studio

A production-ready single-page React + TypeScript AI music studio that generates real songs through Suna AI's public Hugging Face Space via @gradio/client. A prompt-first composer (Simple/Custom modes, six artist presets, editable lyrics, a Turbo/High-Fidelity synthesis engine switch, 24-68s length, optional sing-to-masterpiece vocal upload with a vocal/band mix) feeds the Space's live generate_suna_track endpoint; results land in a session-only library with a Spotify-style near-violet player bar (play/pause, seek, volume, MediaSession metadata), interactive mobile player sheet, telemetry and sung-lyric sheets, and WAV-master downloads. Soft lavender/white palette with a violet accent and honest live states - no fake progress bars.

  • React
  • TSX
  • Tailwind CSS
  • soft-lavender-studio
Pages
1 page
Stack
React + TSX
Theme
Light only
Responsive
Yes
Files
35
License
MIT

Preview

The whole site, live.

Scroll inside the frame, switch viewports, or open the raw preview in a new tab — it is the same file the CLI installs.

Interactive preview
New tab
devsnips.site/templates/react/suna-ai-studio/
iPhone 390 × 844
Fluid 320 → 1920
React/Templates/suna-ai-studio Responsive · Light only · MIT

What's inside

Everything the folder ships.

Straight from the registry's metadata — every line maps to a file you can open in the source tabs below.

  • real AI music generation through Suna AI's public Space via @gradio/client v2 (/gradio_api/info availability probe, /generate_suna_track endpoint)
  • prompt-first composer with Simple and Custom modes, ⌘/Ctrl+Enter submit, and 500-character prompt budget
  • six artist presets (Indila Chanson, Matushka Folk-Pop, Power Ballad, Arena Rock, Afro-Latin Pop, Slap House) with the Space's exact API enum values
  • editable lyrics editor with songbook autofill that matches the Space's preset-change behavior
  • Turbo (8-step) / High-Fidelity (16-step) synthesis engine switch and 24-68s length slider mirroring the Space's controls
  • optional sing-to-masterpiece vocal clip upload (drag & drop, 25MB budget, clip duration read) with a 0.30-1.20 vocal/band mix
  • honest generation states - connecting, composing with a real elapsed timer, queue notices, and Space error text surfaced verbatim; no fabricated progress percentages
  • session-only track library with rename, remove, clear, and copy-prompt; tracks never leave the tab and expire with the Space's temp files
  • Spotify-style near-violet player bar with play/pause, seek slider, seek-ahead/behind, volume, mute toggle, and keyboard shortcuts
  • MediaSession metadata (title, artist, album artwork) for OS media controls
  • expansive NowPlaying card with track stats, Suna telemetry, and the Space's word-aligned sung-lyric sheet
  • full-screen mobile player sheet (dialog, focus trap, Escape to close) and mobile session drawer
  • downloads prefer the Space's 48 kHz 16-bit WAV master, falling back to the 320kbps MP3
  • lavender/white design system: Plus Jakarta Sans + Fraunces, #F6F4FA paper, #211D31 ink, #6F52D9 violet accent, #151220 player
  • semantics - landmark structure, aria-pressed chips, labeled sliders, role=status generation card, focus-visible rings, prefers-reduced-motion handling

Technical

Stack, scripts, structure.

Everything you need to know before you install.

Stack
Framework React
Language TSX
Styling Tailwind CSS
Pages 1
Theme Light only
Style soft-lavender-studio
Dependencies 3 runtime · 8 dev
Scripts npm
npm run dev vite
npm run build tsc --noEmit && vite build
npm run preview vite preview
npm run typecheck tsc --noEmit
Files 35

root 12

  • .gitignore other
  • AGENTS.md doc
  • index.html code
  • metadata.json config
  • package-lock.json config
  • package.json config
  • postcss.config.js code
  • preview.html preview
  • README.md doc
  • tailwind.config.ts code
  • tsconfig.json config
  • vite.config.ts code

src/ 23

  • App.tsx code
  • components/Composer.tsx code
  • components/GenerationPanel.tsx code
  • components/Icon.tsx code
  • components/MobileDrawer.tsx code
  • components/NowPlaying.tsx code
  • components/PlayerBar.tsx code
  • components/PlayerSheet.tsx code
  • components/Sidebar.tsx code
  • components/Slider.tsx code
  • components/SunaMark.tsx code
  • components/TopBar.tsx code
  • components/TrackArtwork.tsx code
  • components/TrackCard.tsx code
  • index.css code
  • lib/clipboard.ts code
  • lib/focus.ts code
  • lib/format.ts code
  • lib/palettes.ts code
  • lib/suna.ts code
  • lib/types.ts code
  • main.tsx code
  • studio/StudioProvider.tsx code

Install

One command, whole folder.

Pulls the template into your project through the DevSnips CLI. The registry path below is stable across the CLI, MCP server and Skills.

terminal · npm
npx devsnips add React/Templates/suna-ai-studio
registry path React/Templates/suna-ai-studio 35 files

AI-ready

Hand the whole job to your agent — Cursor, Cline, Claude Code or Windsurf. One prompt installs the template, fixes the theme toggle, optimises it and reshapes it for what you are building.

Scaffold the DevSnips template "Suna Studio" (React/Templates/suna-ai-studio) into this project, then audit, fix and tailor it.

1. Install — if the DevSnips MCP server is connected, fetch the resource with get_resource(id="React/Templates/suna-ai-studio"). Otherwise run npx devsnips add React/Templates/suna-ai-studio and install the dependencies the template declares.

2. Audit — check the template end to end before changing anything: theme toggling (dark/light), responsive behaviour, accessibility, unused files and assets.

3. Fix — repair what the audit found, starting with the theme toggle: it must persist across reloads, never flash the wrong theme on first paint, and every component must read the same tokens in both modes.

4. Optimise and adapt — trim what the site does not need, then customise the template for the product being built here: replace the placeholder branding, copy, imagery, navigation and routes so it reads as this project rather than as a demo.

Source

Read it before you ship it.

The README, manifest and entry document — verbatim, straight from the registry.

README.md
# Suna Studio Template

A production-ready, single-page **React + TypeScript AI music studio** that generates
**real songs** through [Suna AI's public Hugging Face Space](https://huggingface.co/spaces/johanjomet/suna-ai-studio)
via `@gradio/client`. The page is a prompt-first composer over a soft lavender dashboard,
with a Spotify-style dark player that plays, seeks, and downloads the Space's actual audio.

There is **no mock generation** in this template. Every track is rendered by the live
Space; every state (idle → connecting → composing → ready/unavailable) reflects the real
request, and the honest messages say exactly that.

## Highlights

- **Real generation** — `Client.connect("johanjomet/suna-ai-studio")` + `client.submit("/generate_suna_track", …)`.
- **Prompt-first composer** — Simple and Custom modes, idea chips, ⌘/Ctrl + ↵ submit, 500-char budget.
- **Six artist presets** — Indila Chanson, Matushka Folk-Pop, Power Ballad, Arena Rock, Afro-Latin Pop, Slap House — each stored with the Space's exact API values and its default songbook.
- **Editable lyrics** — the Custom mode exposes the same lyric sheet the Space edits; untouched songbooks follow preset changes just like the Space's UI.
- **Synthesis engine** — Turbo (8 steps) / High-Fidelity SFT (16 steps); **length** 24–68 s.
- **Sing-to-Masterpiece** — optional vocal clip (drop or browse, 25 MB) with a 0.30–1.20 vocal/band mix.
- **Honest states** — a real elapsed timer while the Space renders. Suna's queue exposes no progress percentage, and the UI says so instead of faking one. Space errors (quota, capacity, render failure) surface verbatim.
- **Session library** — tracks live in the tab only; rename, remove, clear, copy prompt.
- **Dark player bar** — near-violet bottom bar with play/pause, seek, ±10 s, volume, mute, MediaSession metadata; a full-screen mobile player sheet + session drawer.
- **Telemetry & lyrics** — the Space's studio telemetry and the word-aligned sung-lyric sheet are kept with each track.
- **Downloads** — prefer the 48 kHz 16-bit WAV master, fall back to the 320 kbps MP3.

## Design direction

**Soft lavender studio** — a calm instrument panel around a serious dark player:

- **Type:** Plus Jakarta Sans (UI, 400–800) + Fraunces (display).
- **Palette:** paper `#F6F4FA`, ink `#211D31`, violet accent `#6F52D9`, night player `#151220`, soft cream `#F5F1FF`.
- **Composition:** rounded 26px cards on a paper canvas, a sidebar + top bar shell, a featured track card that grows out of the composer, and the fixed near-violet player at the bottom. No glassmorphism, no neon, no decorative clutter.

The visual system lives entirely in `tailwind.config.ts` (colors, fonts), `src/index.css`
(tokens, range styling, dialog/drawer rules), and the presentational components — it does
not depend on the shared DevSnips `--ds-*` tokens.

## Structure

```text
suna-ai-studio/
├── index.html                 # Vite entry (theme-color, root mount)
├── package.json               # React 18, @gradio/client 2, Vite 5
├── vite.config.ts
├── tailwind.config.ts         # lavender/white color system, fonts, animations
├── postcss.config.js
├── tsconfig.json              # strict TypeScript
└── src/
    ├── main.tsx               # StrictMode + StudioProvider mount
    ├── App.tsx                # shell: TopBar, Sidebar, composer, session feed, footer
    ├── index.css              # CSS tokens, range styling, dialog/drawer rules
    ├── lib/
    │   ├── suna.ts            # Gradio API adapter: presets, generate, probe, download
    │   ├── types.ts           # Track, SunaGenerateInput, generation + error types
    │   ├── palettes.ts        # artwork palettes
    │   ├── format.ts          # time/bytes helpers + titleFromPrompt
    │   ├── clipboard.ts       # copy helper
    │   └── focus.ts           # focus/keyboard helpers
    ├── studio/
    │   └── StudioProvider.tsx # audio element, generation lifecycle, session state
    └── components/
        ├── Composer.tsx       # Simple/Custom prompt-first composer
        ├── GenerationPanel.tsx# honest generation status card
        ├── TrackCard.tsx      # featured + compact track cards
        ├── NowPlaying.tsx     # expanded current-track panel
        ├── PlayerBar.tsx      # dark bottom player
        ├── PlayerSheet.tsx    # mobile full-screen player dialog
        ├── Sidebar.tsx        # session tracklist (desktop + drawer content)
        ├── TopBar.tsx         # brand + availability status
        ├── MobileDrawer.tsx   # mobile session drawer
        ├── SunaMark.tsx       # brand mark (SVG)
        ├── TrackArtwork.tsx   # generated per-track artwork
        ├── Slider.tsx         # accessible range styling
        └── Icon.tsx           # inline icon set
```

## Setup & run

Requires Node.js + npm. From the template root:

```bash
npm install
npm run dev        # Vite dev server — open the printed URL (usually http://localhost:5173)
```

Production build + local preview:

```bash
npm run build      # tsc type-check + Vite production build → dist/
npm run preview    # serve the built app
```

**Static preview:** `preview.html` at the template root is a self-contained static
prototype of the studio shell (Tailwind CDN + the real palette, composer, and dark player
chrome). It **cannot** generate audio — generation is intentionally disabled in the
preview, and the preview says so. Only the installed app talks to the Space.

## The Suna API contract

Everything lives in `src/lib/suna.ts`. Verified against
`https://johanjomet-suna-ai-studio.hf.space/gradio_api/info` + the Space's source (2026-10):

- `POST /gradio_api/call/v2/generate_suna_track`
- params (in order): `user_prompt` (str) · `artist_preset` (exact enum string) ·
  `custom_lyrics` (str, empty = the preset's songbook) · `duration_sec` (24–68 slider,
  server clips 20–68) · `speed_mode` (Turbo | High-Fidelity SFT enum string) ·
  `uploaded_vocal` (optional fingerprint/file) · `vocal_mix` (0.30–1.20, step 0.05)
- returns `[mp3 FileData, wav FileData, telemetry string, lyricSheet string]`;
  render errors return `[null, null, "⚠️ …", lyrics]`.
- `GET …/gradio_api/info` is used as the availability probe (`/generate_suna_track` must
  exist in `named_endpoints`).

The audio file URLs are Space-hosted `…/gradio_api/file=/tmp/gradio/…` links; they expire
with the Space's temp storage, which is why the library is session-only and downloads are
encouraged.

**Know the external limits.** The Space runs on ZeroGPU with an anonymous run quota; when
the quota is spent for your connection the queue may close with no events — the template
says so honestly and asks you to retry later. Streaming the returned audio from the page
works because the Space sends CORS headers (verified).

## Customization

- **Palette & fonts:** defined once in `tailwind.config.ts` + the token block at the top of `src/index.css`.
- **Presets:** `SUNA_PRESETS` in `src/lib/suna.ts` — ids, labels, palettes, and the default songbook the composer autofills. Keep the `apiValue` strings byte-exact.
- **Engine modes:** `SUNA_QUALITY_MODES`, same byte-exact rule.
- **Copy/ideas:** the `IDEAS` array in `src/components/Composer.tsx` and the shell copy in `src/App.tsx`.
- **Host change:** if you fork/deploy the Space, change the constants at the top of `src/lib/suna.ts` (`SUNA_SPACE_ID`, `SUNA_HOST`).

## Accessibility

- Landmark structure (`header`, `main`, `aside`, `footer`, `form`), single `h1`.
- All controls labeled: sliders (`aria-label`, `aria-valuetext`), toggles (`aria-pressed`/radio groups), player buttons with explicit names.
- Generation status card uses `role="status"`; toasts use a polite live region.
- Player sheet is a native `<dialog>` with focus on close control and Escape to dismiss; the drawer behaves the same.
- Global `:focus-visible` rings; `prefers-reduced-motion` disables floating/idle animations (verified in `src/index.css`).

## Browser support

Modern evergreen browsers. Playback uses native `HTMLAudioElement` with MediaSession;
generation requires WebSockets/SSE for the Gradio queue stream.
141 lines UTF-8 · LF