The Ghost Doesn't Need the Cloud: Building a Local AI Music Curator with Gemma 3 A developer built GhostWave, an open-source, local-first music player and crate manager that uses the open-weight Gemma 3 model via Ollama to organize and curate personal music libraries without a remote LLM API. The app serializes only compact track metadata for the model and validates AI-proposed track IDs against real library records rather than trusting generated IDs. It also includes an audio-reactive visualizer and a Tauri desktop build. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine https://dev.to/challenges/hacktoberfest-week4-2026-10-26 GhostWave is an open-source, local-first music player, crate manager, and audio-reactive visualizer with a Halloween-inspired design. It is built around a simple idea: your music library should remain useful even when the cloud isn't. Most of us have personal music collections that have accumulated over the years: FLAC albums, MP3 downloads, anime soundtracks, Vocaloid tracks, live recordings, and music that might not even be available on streaming platforms anymore. But having the files is only half the problem. Libraries become messy. Metadata goes missing. Filenames become inconsistent. Finding the right tracks for a particular mood can take longer than actually listening to them. GhostWave brings those tasks together in one application: The central feature is the Ghost in the Machine : an open-weight AI model that can help organize your music collection without requiring a remote LLM API. Watch the product film: Links: The product film combines animated product storytelling with recorded application footage. The external metadata responses shown in the scripted walkthrough are demonstration fixtures, not evidence that those particular lookups were performed against live services. A spooky, local-first music player, crate manager, and audio-reactive visualizer powered by local open-weight AI Gemma 3 via Ollama . The Origin Story https://github.com/edgiaxel/GhostWave -the-ghost-in-the-machine-origin-story • Key Features https://github.com/edgiaxel/GhostWave -key-features • Architecture https://github.com/edgiaxel/GhostWave -architecture • Getting Started https://github.com/edgiaxel/GhostWave -getting-started • Local AI Setup https://github.com/edgiaxel/GhostWave -running-local-ai-gemma-3 • Tauri Desktop https://github.com/edgiaxel/GhostWave -tauri-desktop-app • QA & Testing https://github.com/edgiaxel/GhostWave -testing--verification • Deployment https://github.com/edgiaxel/GhostWave -deployment-render An imagined product scenario inspired by seasonal thunderstorms and connectivity concerns Imagine Halloween Eve. Outside, a violent seasonal thunderstorm batters the neighborhood. The grid blinks—and the house plunges into darkness. When power snaps back on ten minutes later, the internet connection is dead. A gathering of friends is waiting for music, but the host's phone streaming app hangs on a spinning wheel: buffering error 404, no connection . An offline backup drive of local music is plugged in—thousands of anime themes, Vocaloid tracks, electronic synths, and classical recordings. But… The most interesting part of the project is how GhostWave turns an AI-generated playlist idea into a proposal grounded in the user's actual music library. Here are two important parts of that implementation. 1. Serialize only the metadata needed by the model Instead of sending audio files or local file paths to the AI, GhostWave builds a compact catalog containing track metadata: static serializeLibrary tracks: Track : CompactTrackSummary { return tracks.map t = { id: t.id, title: t.title, artist: t.artist, album: t.album, genre: t.genre?.length ? t.genre : undefined, durationSeconds: t.durationSeconds, format: t.format, bitrateKbps: t.bitrateKbps, year: t.year, } ; } This gives the model enough context to make selections without including the actual audio bytes or filesystem paths. 2. Resolve AI suggestions against real library records An LLM can generate an ID that looks valid but does not exist. GhostWave doesn't blindly trust the response. The service resolves proposed IDs against the actual library: js const trackMap = new Map allTracks.map track = track.id, track ; const matched: Track = ; const hallucinatedTrackIds: string = ; for const id of plan.matchedTrackIds { const track = trackMap.get id ; if track { if matched.some item = item.id === track.id { matched.push track ; } } else { hallucinatedTrackIds.push id ; } } Unknown IDs are rejected, duplicate selections are avoided, and duration and track-count constraints are enforced by application code rather than trusting the model's arithmetic. The result is a playlist proposal , not an unrestricted AI operation. The user can inspect the selected tracks before saving the crate. Relevant implementation: AiPlaylistService.ts https://github.com/edgiaxel/GhostWave/blob/main/src/services/ai/AiPlaylistService.ts . GhostWave uses a modular TypeScript architecture with React on the frontend and a collection of focused services for audio, AI, metadata, history, and platform integration. Technology stack: music-metadata-browser . gemma3:4b through Ollama. The AI workflow is deliberately separated into several stages: The model is instructed to return a structured response resembling this: { "name": "Fast Electronic Workout", "description": "High-energy electronic tracks", "matchedTrackIds": "track-001", "track-014", "track-027" , "explanation": "Selected for energetic genres and tempo." } The response is not accepted just because it is valid JSON. The application checks its required fields and verifies the proposed IDs against real track records. GhostWave uses Ollama's local API rather than a hosted LLM API. Download the model ollama pull gemma3:4b Start the Ollama service ollama serve The default local endpoint is: http://127.0.0.1:11434 The model must be installed and Ollama must be running for local AI features to work. The core music library and playback features do not depend on Gemma. The project currently reports: The automated checks cover library operations, playback, visualizers, playlist management, AI workflows, metadata handling, and other application features. Some external-provider responses are mocked in automated tests so that the tests remain reproducible. This is different from testing against live third-party services. Music collections are personal. They contain more than just audio files: they preserve memories, interests, and years of discovery. A closed AI service can be convenient, but it also introduces dependencies. Your application may depend on an external API, its pricing, its availability, and the data you must send to use it. Open-weight models and open-source tools give developers another option. With Gemma 3 and Ollama, GhostWave can perform its playlist-curation inference locally. The model does not need a remote LLM subscription, and the catalog sent to that local inference process does not need to include audio files or filesystem paths. It also means developers can inspect and adapt the implementation instead of treating the intelligence as an inaccessible service. There are still important boundaries: Open innovation does not automatically make every integration private or offline. It gives developers the tools and freedom to build systems where those boundaries can be understood, inspected, and controlled. For GhostWave, that means keeping the core music experience local while making external services optional. An imagined scenario inspired by seasonal thunderstorms and connectivity concerns. Imagine Halloween Eve. You're hosting a small gathering with friends. The weather outside is getting rough, and the internet connection suddenly becomes unreliable. Someone tries to start a playlist through a streaming service. It buffers. Then it stops. Fortunately, you have a local music collection: years of Vocaloid tracks, anime soundtracks, synthwave, electronic music, and other recordings. But there's another problem. The library is messy. Some tracks have missing tags, filenames are inconsistent, and finding the right music for the evening is becoming a project of its own. That's the situation GhostWave was designed around. You open your local library, ask Gemma 3 for a spooky electronic playlist, review its suggestions, and start playing. The visualizer responds to the music while the rest of the gathering carries on. No dramatic cloud infrastructure required. Just your music, your machine, and a little ghost in the machine. Hacktoberfest Open-Source AI Challenge — Ghost in the Machine Google Cloud / Gemma Sentry SerpApi Built with React, TypeScript, Gemma 3, Ollama, and a lot of love for local music libraries. Thanks to DEV, GitHub, and MLH for organizing Hacktoberfest 2026