DEV Community

ken109
ken109

Posted on

I Built a Live Wallpaper Engine for macOS — Here's How It Works

Your desktop wallpaper is a static image. It has been since the day you set it up. Mine was too.

Then I thought: what if I could write a React component and have it run as my actual desktop wallpaper? An audio visualizer that reacts to music. A system monitor showing real-time CPU usage. All built with the same tools I use every day.

So I built it.

Audio Visualizer wallpaper running on macOS desktop

Meet Fluxlay — a live wallpaper platform for macOS. Write a React component, and it becomes your desktop wallpaper. I built the desktop app, CLI, SDK, and a gallery (marketplace) for sharing wallpapers.

Show me the code

Here's an audio visualizer wallpaper. The entire thing:

import { useAudio } from "@fluxlay/react";

export default function AudioVisualizer() {
  const { spectrum } = useAudio();

  return (
    <div className="visualizer">
      {spectrum.map((value, i) => (
        <div
          key={i}
          className="bar"
          style={{ height: `${value * 100}%` }}
        />
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

That's it. This reacts to whatever music is playing on your Mac. In real time.

The SDK hooks

The React SDK gives you access to desktop-level data through hooks:

Hook What it does
useAudio() 32-band frequency spectrum, RMS, peak
useSystemMonitor() CPU, memory, battery, network — live
useMousePosition() Global cursor position
useMediaMetadata() Current track, artist, album art
useShell() Run declared shell commands
useTerminal() Embed a terminal in your wallpaper

Yes, you can put a terminal in your wallpaper. No, I don't know why you'd want to. But you can.

The CLI

# Dev server with hot reload
fluxlay dev ./my-wallpaper

# Build and publish to the gallery
fluxlay build ./my-wallpaper
fluxlay publish ./my-wallpaper
Enter fullscreen mode Exit fullscreen mode

fluxlay dev gives you hot reload straight to your desktop. Change a line of CSS, and your wallpaper updates instantly. The DX is genuinely fun.

Architecture

Two layers. Rust handles the OS-level stuff — audio capture, system monitoring, window management. React handles the pixels. They talk over HTTP + NDJSON streams.

The Tauri 2 backend runs an embedded Axum server with streaming endpoints for audio FFT data, system metrics, mouse position, and media metadata. The React SDK subscribes to these streams via hooks. Clean separation. It works surprisingly well.

Why Tauri, not Electron

A wallpaper runs 24/7 in the background. This is not a normal desktop app. Resource consumption is everything.

Electron? 200MB+ binary. Noticeable memory footprint. For a wallpaper, that's a non-starter.

Tauri 2 won because:

  • Tiny footprint — binary size and memory usage are in a completely different league
  • Rust — audio FFT and system monitoring need to be fast and safe. Rust delivers both
  • Direct access to macOS native APIs — ScreenCaptureKit, CoreGraphics, CoreAudio

Rendering a wallpaper behind desktop icons

This was the hardest part. macOS doesn't just let you put a window behind the desktop icons. That's not how the window system works.

I'm using tauri-plugin-desktop-underlay to place the Tauri window at the desktop layer. It renders fullscreen, behind everything, acting as the wallpaper.

Real-time streaming with NDJSON

The SDK talks to the Tauri backend over HTTP + NDJSON (newline-delimited JSON) streams:

React (useAudio) → HTTP GET /v1/audio-stream
                 ← { "spectrum": [...], "rms": 0.42, "peak": 0.87 }\n
                 ← { "spectrum": [...], "rms": 0.38, "peak": 0.91 }\n
                 ← ...
Enter fullscreen mode Exit fullscreen mode

I considered WebSocket, but NDJSON plays nicer with Tauri's built-in Axum server. Plus, you can debug it with curl. That sold me.

Real-time FFT in Rust

Making wallpapers react to music means real-time audio analysis. Here's what happens on the Rust side:

  1. Capture system audio output via macOS APIs
  2. FFT with rustfft
  3. Resample to 32 logarithmic bands
  4. Calculate RMS and peak values

The logarithmic scale matters. Human hearing is more sensitive to low frequencies. Linear scaling makes the visualizer look flat and boring. This single adjustment made the audio visualizer go from "meh" to "whoa."

The stack

Layer Tech
Desktop app Tauri 2 + Rust
Wallpaper UI React 19
SDK @fluxlay/react (hooks-based)
CLI Node.js
Native module Rust + NAPI-RS
Website TanStack Start + Cloudflare Workers
API Go + ConnectRPC

What's next

Honestly, there's a lot left to do:

  • Performance optimization — a wallpaper runs constantly, so every percent of CPU matters. Heavy animations on multiple monitors still need work
  • Windows support — currently macOS only. Desktop layer APIs are completely different on Windows, so this is the biggest challenge
  • SDK expansion — Unity WebGL builds as wallpapers, more data sources

Right now the gallery only has my own wallpapers — six of them. I'd love to see what other people build. The SDK is open, the CLI handles publishing, and the gallery is ready for new creators.

Get started in 3 minutes

"React for wallpapers" sounds niche. It is. But there's something deeply satisfying about passing useAudio().spectrum into a div's height and watching your desktop come alive.

Here's how to try it:

  1. Download the appfluxlay.com
  2. Install the CLInpm install -g @fluxlay/cli
  3. Scaffold & runfluxlay dev ./my-wallpaper

That's it. You're editing a React app that renders directly on your desktop. The docs walk you through the SDK hooks, publishing, and everything else.

If you build something cool, I'd genuinely love to see it. Drop a link in the comments or publish it to the gallery.

👉 fluxlay.com

Top comments (0)