Back to Audio
Components / Audio
Now Playing Bar
Free Audio React component — NowPlayingBar. MIT licensed, copy-paste ready for Next.js and Tailwind CSS.
Compact dark player bar with artwork, track info, transport controls, and a scrubber. The footer bar every music app eventually needs.
Preview

Midnight Dreams
The Weekend
Setup
How to use
Free for personal and commercial use. No UI attribution required. Include the MIT copyright notice when copying component source into your project. Read the MIT license.
- 1
Run in your terminal:
$npm install clsx tailwind-merge lucide-react - 2
Copy
lib/cn.tsbelow. Skip if you already havecn(). - 3
Copy the code below and create
components/audio/now-playing-bar.tsxin your project. - 4
Import and render:
Exampleimport { NowPlayingBar } from "@/components/audio/now-playing-bar";
lib/cn.ts
import { type ClassValue, clsx } from "clsx";import { twMerge } from "tailwind-merge";export function cn(...inputs: ClassValue[]) {return twMerge(clsx(inputs));}
components/audio/now-playing-bar.tsx
"use client";import { forwardRef, type ComponentPropsWithoutRef, useState } from "react";import Image from "next/image";import { cn } from "@/lib/cn";import { Play, Pause, SkipForward, SkipBack } from "lucide-react";export type NowPlayingBarProps = Readonly<{title?: string;artist?: string;progress?: number;artwork?: string;defaultPlaying?: boolean;} & ComponentPropsWithoutRef<"div">>;// Production-ready Now Playing component — styled with Tailwind CSS.export const NowPlayingBar = forwardRef<HTMLDivElement, NowPlayingBarProps>(({className,title = "Midnight Dreams",artist = "The Weekend",progress = 60,artwork = "/wallpaper-3.png",defaultPlaying = true,...props},ref,) => {const [playing, setPlaying] = useState(defaultPlaying);return (<divref={ref}data-slot="now-playing-bar"className={cn("flex w-80 items-center gap-3 rounded-2xl border border-neutral-800 bg-neutral-950 px-3 py-3 font-sans shadow-lg",className,)}{...props}><divdata-slot="now-playing-bar-artwork"className="relative h-10 w-10 shrink-0 overflow-hidden rounded-lg"><Imagesrc={artwork}alt={title}fillsizes="40px"className="object-cover"/></div><div data-slot="now-playing-bar-info" className="min-w-0 flex-1"><p className="truncate text-xs font-medium text-white">{title}</p><p className="truncate text-[10px] text-neutral-500">{artist}</p></div><divdata-slot="now-playing-bar-controls"className="flex items-center gap-2"><buttontype="button"aria-label="Previous track"className="cursor-pointer text-sm text-neutral-500 transition-colors hover:text-white"><SkipBack size={14} /></button><buttontype="button"aria-label={playing ? "Pause" : "Play"}onClick={() => setPlaying(!playing)}className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-full bg-white text-xs text-neutral-900 transition-transform hover:scale-105">{playing ? (<Pause size={14} fill="black" />) : (<Play size={14} fill="black" />)}</button><buttontype="button"aria-label="Next track"className="cursor-pointer text-sm text-neutral-500 transition-colors hover:text-white"><SkipForward size={14} /></button></div><divdata-slot="now-playing-bar-progress"className="hidden h-1 w-16 overflow-hidden rounded-full bg-neutral-800 sm:block"><divclassName="h-full rounded-full bg-emerald-500"style={{width: `${Math.min(Math.max(progress, 0), 100)}%`,}}/></div></div>);},);NowPlayingBar.displayName = "NowPlayingBar";