Profile

Technical report: Indian nostalgia music web apps

Technical report: Indian nostalgia music web apps

Prepared: 15 August 2026
Scope: 30 unique sites from the supplied list (three repeated entries were deduplicated).
Method: live-page, response-header, JavaScript-bundle, asset, and network-endpoint inspection. This is a black-box implementation review, not a source-code or infrastructure audit. “No backend observed” means the inspected public client did not require an application API for its main experience; it does not prove that no private build or operational service exists.

Executive conclusion

These apps are visually elaborate but technically simple. The recurring architecture is:

  • a static page or client-rendered React app;
  • a YouTube IFrame player using hard-coded video or playlist IDs;
  • local images, animation, horns, ambience, or sound effects;
  • optional outbound Spotify and YouTube Music links;
  • occasionally, a tiny API or realtime database for a genuine listener count.

A server backend is not required for the core product. A public or unlisted YouTube/YouTube Music playlist can play directly in the browser. Spotify also supports browser embeds. A backend becomes useful only for features such as real concurrent listener counts, synchronized rooms, accounts, likes, chat, moderation, private catalog administration, or protected third-party credentials.

For a new version of this concept, the most sensible starting point is plain HTML/CSS/JavaScript + the YouTube IFrame Player API + Cloudflare Pages. GitHub Pages is equally capable of the core experience and is the simplest choice when the project already lives in GitHub. Use Vercel when the implementation genuinely benefits from Next.js or server functions—not merely because many examples use a free .vercel.app address.

flowchart TD
    H["Static host<br/>Pages or Vercel"] --> B["Browser UI<br/>HTML or React"]
    B --> M["YouTube IFrame<br/>or Spotify Embed"]
    B -. "optional" .-> F["Functions / presence API"]
    F --> R["Realtime state<br/>Supabase or Durable Object"]

Site-by-site technical findings

In the final column, No means no server is needed for playback and none was observed in the public client. Optional extra means the music player remains static, but an ancillary feature makes a network call. Yes means the currently presented experience uses backend/realtime behavior.

App Observed frontend Delivery observed Music source Server-backend verdict
saloon.wtf Next.js + React Cloudflare edge; origin not established YouTube IFrame playback; iTunes preview/metadata URLs also present; Spotify and YouTube Music outbound links No for playback; no app API observed
truckplaylist.wtf Single vanilla HTML/CSS/JS page Vercel Hard-coded YouTube video IDs through the IFrame API; active YouTube Music playlist link No
hornokplease.xyz Vanilla HTML/CSS/JS; JSON track list Vercel YouTube IFrame; locally hosted horn sound effect No; code comments identify the listener count as decorative
safar-e-up.vercel.app Vite + React Vercel YouTube IFrame player No
marathi-songs.vercel.app Vanilla HTML/CSS/JS Vercel YouTube IFrame; Spotify and YouTube Music links No; client code explicitly implements a fake online counter
madrasradio.vercel.app Next.js + React Vercel Embedded YouTube playlists by mood; Spotify playlist links No
kannada2000s.vercel.app Next.js + React Vercel YouTube playlist player No
naada-blr.vercel.app Vanilla HTML/CSS/JS Vercel YouTube IFrame; Spotify and YouTube Music links Optional extra: /api/presence supplies a live count; playback itself is static
sindhi-lada.vercel.app Vanilla HTML/CSS/JS Vercel YouTube/YouTube Music playlist via IFrame API No; displayed listener number is generated locally
gediroute.vercel.app Astro shell + React island Vercel YouTube IFrame with individual video IDs No
bihar-parivahan-nigam.vercel.app Next.js + React Vercel YouTube playlist/player No; no live-count endpoint observed
chacharchok.vercel.app Next.js + React Vercel YouTube IFrame; Spotify outbound links No
mazdoor-radio.vercel.app Next.js + React Vercel Hard-coded YouTube IDs; YouTube search fallback Yes for extras: /api/presence and /api/youtube/search; hard-coded playback does not intrinsically need them
chaitapri.vercel.app Next.js + React Vercel Spotify playlist iframe and Spotify link No
chaiwala.live Vite + React Vercel YouTube Music playlist through IFrame API; local chai ambience No
busdriver.wtf Next.js + React Cloudflare edge; origin not established YouTube IFrame with playlist IDs Yes: WebSocket endpoint at /api/listeners for concurrent listeners
roadways-wala.ai.studio Vite + React Google Frontend / AI Studio YouTube playlist iframe No
construction-site-lac.vercel.app Next.js + React Vercel YouTube playlist/player; local effects Yes for presence: Supabase Realtime client; playback remains browser-only
auto-wala.vercel.app Vanilla HTML/CSS/JS; JSON track list Vercel YouTube IFrame; local horn MP3s No
pan-wala.vercel.app Vanilla HTML/CSS/JS Vercel YouTube IFrame; Spotify outbound link No; third-party analytics/ads only
deluxesaloon.space Next.js + React Cloudflare edge; origin not established YouTube/YouTube-nocookie embeds; Spotify and YouTube Music links No; no app API observed
apnadhaba.com Vanilla inline HTML/CSS/JS hcdn edge; provider not conclusively established YouTube IFrame; Google Tag Manager No
mehfil-eosin.vercel.app Next.js + React Vercel YouTube playback; Spotify and YouTube Music links No
gali-fm.vercel.app Vanilla ES-module HTML/CSS/JS Vercel YouTube playlist; local ambient MP3s Optional external services: Firebase Analytics and an external visitor counter; no own playback backend observed
musafir.vercel.app Vite-built vanilla JS/TypeScript Vercel YouTube playlist/video IDs; local horn/ambience asset No
90s-toon.vercel.app Vanilla HTML/CSS/JS Vercel YouTube iframe embeds No
wohdin.xyz Next.js + React Vercel YouTube IFrame API No; no live-count endpoint observed
chai-tapri-nine.vercel.app Vite + React Vercel Hard-coded YouTube video IDs No
cutting-chai-xi.vercel.app Vanilla HTML/CSS/JS; JSON track list Vercel YouTube IFrame No
hornokplease-delta.vercel.app Single static HTML/CSS/JS page Vercel YouTube IFrame No

What the matrix says

  • YouTube is the de facto audio layer. Twenty-nine of the 30 sites use YouTube playback. The exception found was chaitapri, which uses a Spotify embed.
  • Spotify is usually a destination link, not the player. It gives users a way to open or save the collection in Spotify while the site itself keeps the more controllable YouTube player.
  • The apps do not generally host the songs. Locally hosted audio is mostly horns, traffic, chai-shop ambience, or another short effect. That is technically and legally different from serving a catalogue of commercial recordings.
  • Framework complexity is unrelated to the essential feature. The same product appears as one HTML file, Vite/React, Astro/React, and Next.js. React helps manage a rich interactive scene, but it is not required to play a playlist.
  • “12 people listening” is not evidence of a backend. Several counters are visibly generated in the client. Only naada-blr, mazdoor-radio, busdriver, and construction-site-lac exposed a presence/API/realtime mechanism during inspection.

Does this product need a server backend?

No backend needed

A completely static build can provide:

  • the illustrated scene and animations;
  • play/pause, next/previous, volume, shuffle, and playlist traversal through the YouTube IFrame API;
  • a Spotify playlist embed;
  • local UI preferences using localStorage;
  • horns and ambience stored as site assets;
  • analytics from a third-party script;
  • deployment to GitHub Pages, Cloudflare Pages, or Vercel.

The browser talks directly to YouTube or Spotify. There is no need to proxy the stream, store the songs, or run a database.

Backend justified

Use a small server/API only when the feature requires shared or protected state:

Feature Why a backend is needed Lightweight implementation
Real concurrent listener count Browsers must register presence and expire disconnected users Cloudflare Durable Object, Supabase Realtime, or a WebSocket/presence function
Synchronized “radio room” One shared track position must be authoritative Durable Object/WebSocket room or realtime database
Accounts, likes, history Durable per-user storage and authentication Managed auth + database
Chat or requests Shared state, moderation, abuse controls Realtime backend plus rate limiting
Search or catalogue administration The app may need API quotas, caching, or a protected secret Serverless function with secret stored server-side
Private Spotify functionality OAuth tokens and refresh flows need careful handling Server-side OAuth/token exchange

Do not add a server solely to display a decorative number. Either label it as part of the fiction (“the shop feels busy tonight”) or omit it; presenting random values as live telemetry is misleading.

Hosting comparison

All three services can host the essential static version and attach a custom domain with HTTPS. A custom domain is purchased separately; their free addresses are typically project.vercel.app, project.pages.dev, and account.github.io/project.

Capability Vercel Cloudflare Pages GitHub Pages
Best fit Next.js, React deployments, preview environments, serverless APIs Static/Vite/React sites with a strong edge network and optional Workers/Functions Straightforward static sites published from a GitHub repository
Static HTML/CSS/JS Yes Yes Yes
Build from Git Yes; preview deployments are first-class Yes; branch/preview deployments are first-class Yes through Pages/Actions; PR previews are not a comparable default product feature
Backend option Vercel Functions; current platform also documents WebSocket support Pages Functions on Workers; Durable Objects are a strong fit for stateful realtime rooms None in Pages; call an external backend
Next.js experience Strongest and most native Static export is easy; full server-rendered Next.js generally needs the Cloudflare Workers/OpenNext route Static export only
Realtime presence Possible, but introduces server/state architecture Particularly suitable with Workers + Durable Objects Requires Supabase, Firebase, or another external service
Free-plan caveat Hobby is for personal, non-commercial use; check plan terms before monetising Static asset requests are free/unlimited; Functions consume Workers quotas; build/file limits apply Static-service limits apply; GitHub says Pages is not intended to run an online business or SaaS
Operational overhead Low, especially for Next.js Low for static sites; modest when adding Workers state Lowest for a purely static repo

Relevant current documentation: Vercel Hobby terms, Vercel deployments and previews, Vercel Functions, Vercel WebSockets, Cloudflare Pages limits, Pages Functions, Pages Functions pricing, Cloudflare Durable Object WebSockets, what GitHub Pages is, and GitHub Pages limits.

Practical choice

  1. Cloudflare Pages — recommended default. It offers the static simplicity of GitHub Pages, useful preview deployments, and a clean upgrade path to Functions or Durable Objects if genuine realtime presence is later added.
  2. GitHub Pages — recommended if the site is already a simple public GitHub project. It is sufficient for the entire music experience. Do not migrate merely to get a YouTube player.
  3. Vercel — recommended when choosing Next.js or needing its deployment/server-function workflow. It is excellent at that job, but a one-page nostalgia radio does not intrinsically need Next.js, and commercial use requires attention to the plan terms.

Hosting limits and plan terms change, so they should be rechecked before launch or monetisation.

Music source: YouTube vs YouTube Music vs Spotify

YouTube and YouTube Music

YouTube Music playlists use the same underlying playlist-ID model as YouTube. In a URL such as:

https://music.youtube.com/playlist?list=PLxxxxxxxx

the reusable identifier is everything after list=. If the playlist is public or unlisted, it can usually be embedded directly:

<iframe
  width="480"
  height="270"
  src="https://www.youtube.com/embed?listType=playlist&list=PLxxxxxxxx"
  title="Nostalgia playlist"
  allow="autoplay; encrypted-media; picture-in-picture"
  allowfullscreen>
</iframe>

For custom buttons and track events, use the YouTube IFrame Player API with listType: "playlist" and the playlist ID. Merely playing the playlist does not require the YouTube Data API, an API key, or a backend. The player parameter documentation gives the official embed format.

Limitations:

Spotify

A public Spotify playlist can be added with a Spotify Embed without building a custom audio backend. Spotify’s embed tutorial and IFrame API cover the standard widget and limited programmatic control.

The Spotify Web Playback SDK is a different, much heavier choice: it provides custom playback but requires Spotify authorization, a Premium user for Web Playback, token handling, and compliance with Spotify’s platform restrictions. Spotify also tightened development access in 2026: development-mode apps are limited to a Premium owner, one Client ID, and up to five authorized users, according to its developer-access update. That makes it a poor foundation for a casual public microsite unless the product truly needs Spotify-native playback.

Can an existing YouTube/YouTube Music playlist be reused?

Yes—directly, and that is the recommended route. Make the playlist public or unlisted, copy its list= ID, and use the YouTube playlist embed or IFrame Player API. No playlist migration is needed.

Spotify cannot directly play a YouTube playlist. To offer the same collection in Spotify, recreate it there or use a playlist-transfer service to match tracks, then embed or link the resulting Spotify playlist. Matching is imperfect because catalogues, editions, remasters, and regional availability differ.

For this particular genre of experience, YouTube is the better primary source:

  • the playlist already exists there;
  • rare regional songs, television themes, and older uploads are often easier to find;
  • it supports playlist playback and custom site controls without user login;
  • almost the entire inspected peer set already uses the same architecture.

Spotify is best retained as an optional “Open in Spotify” link or standard embed for users who prefer its library.

Version 1: static, no backend

site/
├── index.html
├── styles.css
├── player.js
├── assets/
│   ├── scene.webp
│   ├── horn.mp3
│   └── ambience.mp3
└── README.md

Use plain JavaScript unless the interface contains enough independent state—animated characters, scene modes, queue editing, responsive panels—to make React materially easier to maintain. Keep playlist IDs in a small configuration object. Deploy to Cloudflare Pages or GitHub Pages.

Version 2: add only proven features

  • Add privacy-friendly analytics if there is a concrete measurement question.
  • Add a presence service only when “people listening now” is meant to be real.
  • Add Next.js/server functions only when there is actual server behavior.
  • Keep songs on YouTube or Spotify; locally host only original/licensed scene audio and effects.

Compliance and UX cautions

  • Do not download and re-host commercial songs without the necessary rights.
  • Do not copy the tiny hidden-player technique visible in some examples. YouTube’s player documentation says embedded players must have a viewport of at least 200 × 200 pixels. Provide a compliant visible player surface, even if the rest of the experience uses custom controls.
  • Start audio after a clear user action and provide pause, volume, and mute controls.
  • Provide fallback links to the original playlist when a browser blocks playback.
  • Treat title/artist metadata as display data, not ownership evidence.

Bottom line

The winning implementation is not a media-streaming platform. It is a static interactive scene wrapped around an official third-party player. Start with HTML/CSS/JavaScript, a reusable YouTube Music playlist ID, and Cloudflare Pages or GitHub Pages. Introduce a backend only for a feature that genuinely requires shared state. That keeps the site inexpensive, fast, portable, and much easier to maintain.