Skip to content
 
 

Repository files navigation

🎧 Noize

Background & white noise to help you relax or focus.
Ten looping pixel-art scenes, ten ambient tracks, zero sign-ups.

Open the app →

React 18 Vite 6 Node 20 Deploy


What it is

Pick a scene — a waterfall, a thunderstorm, a café, a snowy blizzard — and it loops as full-bleed video while its ambient track plays. That's the whole app.

This is a recreation of a lovely little project originally built by kartiknair, rebuilt on modern tooling with the original art and sounds kept intact. Credits for every artist and sound live on the in-app about page.

Highlights

🌗 Dark mode Follows prefers-color-scheme by default, overridable with the toggle, remembered in localStorage, and applied before first paint so there's no flash of the wrong theme.
📱 iOS-friendly audio MP3s are served from the Pages site itself so Safari actually plays them (see Audio pipeline). Videos use playsInline so iOS doesn't hijack them into fullscreen.
🎞️ Video with GIF fallback Each scene is an .mp4; if <video> errors, the component swaps in the .gif.
📦 Zero runtime deps React and ReactDOM. That's it.
🚀 Push-to-deploy Every push to master builds and publishes to GitHub Pages via Actions.

Quick start

nvm use          # Node 20 (see .nvmrc); Node 18+ works
npm ci
npm run dev      # http://localhost:5173

Heads up: in local dev the audio files aren't present — they're fetched at deploy time, not stored in git (see below). The UI, scenes, and theming all work; only playback is silent. Drop the ten MP3s into public/audio/ if you want sound locally.

Scripts

Script What it does
npm run dev Vite dev server with HMR at localhost:5173.
npm run build Production build into dist/ (minified, hashed filenames).
npm run preview Serves the built dist/ locally to sanity-check a release.

Project layout

index.html          entry + no-flash theme script
src/
  index.jsx         createRoot + StrictMode
  App.jsx           view switching (library / song / about)
  Library.jsx       grid of scenes; builds the audio + image URLs
  SongCard.jsx      one scene tile, video with gif fallback
  SongPage.jsx      full-bleed scene + <audio> player
  About.jsx         credits
  ThemeToggle.jsx   sun/moon toggle
  theme.js          theme resolution + persistence
  media.js          import.meta.glob → hashed asset URLs
  images/           iN.mp4 + iN.gif (bundled, 10 scenes)
public/             favicon, manifest, robots.txt
.github/workflows/  deploy.yml

Infrastructure

Build

Vite 6 with @vitejs/plugin-react. base is ./ (relative), so the same build works at a Pages sub-path (user.github.io/noize/), behind a custom domain, or at a site root — no rebuild, no config swap.

Scene media is bundled from src/images/. Because Vite has no webpack-style dynamic require(), src/media.js eagerly globs every .mp4/.gif and maps the ./images/iN keys the components use onto their final hashed URLs.

Audio pipeline

The ten MP3s are not in git and not hotlinked — they're stored as a GitHub Release asset (audio-v1) and pulled into dist/audio/ by the deploy workflow, so they ride along inside the Pages artifact.

The detour matters on iOS:

  • GitHub Releases serve application/octet-stream + Content-Disposition: attachment → Safari refuses to play them.
  • GitHub Pages serves audio/mpeg inline with range-request support → works everywhere, iOS included.

At runtime Library.jsx builds URLs as ${import.meta.env.BASE_URL}audio/aN.mp3, which keeps them correct under any deploy base. Earlier versions streamed from a Backendless CDN; that dependency is gone.

Deployment

.github/workflows/deploy.yml runs on every push to master (and on manual dispatch):

checkout → setup-node 20 (npm cache) → npm ci → npm run build
        → curl the 10 MP3s into dist/audio/
        → upload-pages-artifact → deploy-pages

It uses OIDC (id-token: write) with the official Pages actions — no gh-pages branch, no tokens to manage. Concurrency is capped to one deploy, with newer pushes cancelling in-flight runs.

One-time setup in a fork: Settings → Pages → Source → GitHub Actions, then upload the audio as a Release tagged audio-v1 (or point the curl loop at wherever you host it).

History

Started life as a Create React App project on react-scripts@3.3.0, which no longer builds on modern Node (webpack 4 needs OpenSSL's removed MD4 hash). It was migrated to Vite + React 18, and dead weight — firebase, a Universal Analytics react-ga snippet, the CRA service worker — was dropped along the way. Full notes in PLAN.md.

About

Web app for background/white noise to relax or focus

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages