A community-driven, open-source fan site for exploring your favorite Vocaloid virtual singers — their bios, music, and more.
Built with plain HTML, CSS, and JavaScript. No frameworks, no build tools — just serve it over HTTP and go.
- Hash routing — back/forward navigation and shareable URLs for every page
- Category browsing — filter vocalists by VOCALOID, UTAU, VSYNTH, or OTHER with a dynamic grid
- Square & list layout modes with real-time search filtering
- Individual vocalist pages with bios, embedded YouTube music, shareable links, and trivia
- Profile page — recently viewed vocalists shown as quick-access cards
- Vocalist of the Day — a daily featured vocalist on the welcome screen with animated bursting stars
- Did You Know — per-vocalist trivia box with accent branding
- SURPRISE ME button — jumps to a random vocalist
- Clickable welcome dots — navigate directly to any vocalist from the home screen
- Music section — sortable by title, artist, album, or date (newest / oldest first) with song count badge
- Skeleton loading — shimmer placeholders while data loads
- Light / dark theme toggle with localStorage persistence
- Sound clips on vocalist page navigation (click a vocalist card or visit their page)
- Favorites — star a vocalist to save them to your profile page, with scale-bounce animation
- Offline indicator — red "OFFLINE" badge in the navbar when you lose connection
- Share modal — native Web Share API with clipboard fallback, social preview card, animated close
- Social meta tags — OG and Twitter cards update dynamically per page
- PWA support — installable as a standalone app (minimal passthrough service worker, no caching)
- Custom scrollbar — theme-aware with vocalist accent color on active drag
- Per-vocalist selection highlight —
::selectioncolor matches the current vocalist - Animated welcome screen, section transitions, staggered card entrance, modal close, and scroll-to-top button
- Fully community-expandable — new vocalists need a JSON entry, portrait and sign images, a divider strip, a CSS color variable, and a welcome dot rule
vocaloid-web/
├── index.html
├── README.md
├── CONTRIBUTING.md
├── LICENSE
├── manifest.json # PWA manifest
├── sw.js # Service worker (passthrough, no caching)
├── sitemap.xml # SEO sitemap
└── src/
├── assets/
│ ├── img/
│ │ ├── <vocalist>.webp # vocalist portrait images (yixi uses .png)
│ │ ├── dividers/
│ │ │ ├── divider-gumi.png
│ │ │ ├── divider-luka.png
│ │ │ ├── divider-miku.png
│ │ │ ├── divider-neru.png
│ │ │ ├── divider-teto.png
│ │ │ ├── divider-yixi.png
│ │ │ └── divider-yuki.png
│ │ ├── signs/
│ │ │ └── sign-<vocalist>.png # error screen images
│ │ └── icons/
│ │ ├── icon.svg # PWA icon, favicon, OG image
│ │ ├── chevron-up.svg # scroll-to-top button
│ │ ├── dice.svg # surprise me button
│ │ ├── search.svg
│ │ ├── share.svg # share modal
│ │ ├── sound.svg # sound toggle
│ │ ├── star.svg # favorites star
│ │ ├── sun-moon.svg # theme toggle
│ │ └── votd-star.svg # vocalist of the day star
│ └── sound/
│ ├── miku/ # vocalist audio clips
│ ├── neru/
│ └── teto/
├── components/ # custom HTML elements
│ ├── aboutSection.js
│ ├── errorSection.js
│ ├── heroSection.js
│ ├── musicSection.js
│ ├── navbar.js
│ ├── profileSection.js
│ ├── shareModal.js
│ ├── vocalistGrid.js
│ ├── welcomeDots.js
│ └── welcomeSection.js
├── css/
│ ├── global.css # manifest — imports all partial CSS files below
│ ├── reset.css # universal reset & box-sizing
│ ├── variables.css # light/dark theme CSS custom properties
│ ├── layout.css # body background, about section, scrollbar, ::selection
│ ├── welcome.css # welcome section, Vocalist of the Day with animated stars
│ ├── navbar.css # navbar, other/theme buttons
│ ├── hero.css # hero section, share button, share modal, Did You Know
│ ├── vocalists.css # vocalist-branded welcome dot rules
│ ├── singers.css # vocalist grid (square/list), search, skeleton, song count
│ ├── profile.css # profile page recently-viewed cards
│ ├── divider.css # animated divider strip
│ ├── error.css # error page
│ ├── music.css # music search, controls, cards, skeleton
│ ├── responsive.css # mobile/tablet breakpoints
│ └── animations.css # keyframe animations (staggered cards, modal, etc.)
├── js/
│ ├── errorHandler.js # error screen logic
│ ├── favoritesHandler.js # favorites (star) persistence
│ ├── musicHandler.js # music fetch, sort, render, song count
│ ├── musicSearchHandler.js # search filtering + init listeners
│ ├── offlineHandler.js # online/offline detection
│ ├── pageRenderer.js # hash-driven router, social meta, selection color, recently-viewed tracking
│ ├── scrollToTop.js # scroll-to-top button
│ ├── soundHandler.js # audio clip playback
│ ├── svgLoader.js # fetches SVGs and injects them inline
│ ├── themeHandler.js # dark/light theme toggle
│ ├── vocalistOfTheDay.js # deterministic daily vocalist picker + renderer
│ ├── welcomeDotsRenderer.js # welcome dot population
│ └── swManager.js # service worker registration
└── json/
├── vocaloidNames.json # list of active vocalist slugs
├── error/
│ └── error.json # random error titles
├── vocals/ # per-vocalist bio data
│ ├── gumi.json
│ ├── luka.json
│ ├── miku.json
│ ├── neru.json
│ ├── rin-len.json
│ ├── teto.json
│ ├── yixi.json
│ └── yuki.json
├── ytmusic/ # per-vocalist music playlists
│ ├── gumiMusic.json
│ ├── lukaMusic.json
│ ├── mikuMusic.json
│ ├── neruMusic.json
│ ├── rin-lenMusic.json
│ ├── tetoMusic.json
│ ├── yixiMusic.json
│ └── yukiMusic.json
└── error/
└── error.json # random error titles
No install required. Just serve the folder over HTTP — opening index.html directly as a file:// URL will cause CORS errors on the JSON fetches.
Option 1 — VS Code Live Server (easiest)
Install the Live Server extension, right-click index.html → Open with Live Server.
Option 2 — Node.js
npx serve .Option 3 — Python
python -m http.server 8080Then open http://localhost:<port> in your browser.
See CONTRIBUTING.md for the full guide. The short version:
- Add the slug to
src/json/vocaloidNames.json - Create
src/json/vocals/<slug>.json(include"type":"vocaloid","utau","vsynth", or"other"; optionally add"dyk"trivia text) - Create
src/json/ytmusic/<slug>Music.json - Add the vocalist's portrait image to
src/assets/img/ - Add the divider strip image to
src/assets/img/dividers/ - Add the error screen sign image to
src/assets/img/signs/ - Add a CSS color variable in
src/css/variables.css(both light and dark themes) and a welcome dot rule insrc/css/vocalists.css
| Layer | What's used |
|---|---|
| Structure | Vanilla HTML5 with custom elements (customElements.define) |
| Styling | Vanilla CSS with custom properties (CSS variables) |
| Logic | Vanilla JavaScript (no frameworks) |
| Fonts | Bebas Neue via Google Fonts |
| Icons | Custom SVGs loaded via svgLoader.js (inline injection for currentColor) |
| Data | Local JSON files |
| PWA | Minimal passthrough service worker (no caching), Web App Manifest |
We welcome contributions! Please read CONTRIBUTING.md before opening a pull request.
| Source | Used for |
|---|---|
| Vocaloid Wiki | Vocalist metadata |
| Vimalion | Yi Xi's data |
| YouTube | Music embeds |
| Lucide | Icons |
All content is for informational and entertainment purposes only. We do not claim ownership of any music, images, or information presented here. All rights belong to their respective creators and copyright holders. We do not host music — we link to publicly available content on YouTube.
This project is open source. See LICENSE for details.
Created by NeoVoid (ItsFoxCrafter) and maintained by the community.