English | 中文
foo_ui_webview2
Documentation: https://nereafantasia.github.io/foo_ui_webview2/
A modern UI component for foobar2000 built on WebView2 (C++ DLL). It turns the entire foobar2000 window into a WebView2 canvas, letting you build the interface with modern web technologies while keeping native Windows 11 visual effects (Mica/Acrylic).
- Version: 1.12.0
- License: GPL-3.0-or-later (main component) / MIT (
sdk/)
Features
- Full WebView2 UI — the entire client area is rendered by WebView2; build it with plain HTML/CSS/JS or any framework (Vue, React, …)
- Runs three ways — standalone full-UI replacement, DUI panel, or CUI panel
- Native Windows 11 effects — Mica / Acrylic / Tabbed backgrounds
- Extended title bar into the client area — custom title bar content, Snap Layout support
- Bidirectional C++ / JS bridge (BridgeCore) — player state and events pushed to your UI in real time
- 200+ APIs across 20+ namespaces
- Multi-window system — popup windows, cross-window messaging, async close handling
- Web Components library (fb-* elements) and a typed TypeScript SDK on npm
- SMP compatibility layer — Spider Monkey Panel knowledge and much existing code carry over
- MCP Server — AI agent integration via CDP
- Plugin extension system (PluginRegistry) — other components can expose APIs to your UI
Why foo_ui_webview2?
foobar2000 already has excellent customization stacks; this component occupies a different spot in the trade-off space:
| foo_ui_webview2 | JS panel hosts (JSplitter / SMP) | WebView panel components (foo_uie_webview / foo_webview2) | |
|---|---|---|---|
| UI technology | Web platform — HTML/CSS/JS, any framework, Chromium DevTools | JavaScript over GDI/GDI+ drawing callbacks | Web platform |
| Runs as | Standalone full UI, DUI/CUI panel, popup windows | Panel / splitter inside DUI or CUI | Panel inside DUI or CUI |
| Player integration | Built-in bridge — playback, playlists, media library, metadata, artwork, queue, config, and more in one component | Mature, battle-tested script API with a large existing theme ecosystem | Host-object API centered on the panel and rendering |
| Native windowing | Fullscreen, Mica/Acrylic, custom caption, multi-window (standalone mode) | Managed by the host UI | Managed by the host UI |
| Skill / code reuse | Web skills; SMP knowledge via the compatibility layer | Existing SMP / JScript scripts and skills | Web skills |
| AI tooling | MCP server included | — | — |
These stacks compose rather than exclude each other: this component itself runs as a CUI/DUI panel next to your existing layout, and other foobar2000 components can register APIs into its bridge through PluginRegistry.
Quick start (30 seconds)
- Install the
.fb2k-componentpackage, then pickWebview2 UIunderFile → Preferences → Display → Default User Interface(installation guide). - Save this as
<profile>\webview-ui\default\index.html(create the folders if needed):
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>My foobar2000 UI</title></head>
<body>
<h1 id="track">Waiting for playback...</h1>
<button id="play">Play / Pause</button>
<script>
document.getElementById('play').onclick = () => fb2k.invoke('playback.playOrPause');
fb2k.on('playback:trackChanged', (data) => {
document.getElementById('track').textContent = data.artist + ' - ' + data.title;
});
</script>
</body>
</html>
- Restart foobar2000.
No SDK files, no Node.js, no build step — the fb2k bridge is injected natively by the component. Until you deploy a template, the component shows a built-in test page with clickable API demos, so a fresh install is never a blank window.
Templates & themes
The component ships without a built-in frontend. Place your WebUI under your foobar2000 profile directory at webview-ui\<template>\, with index.html as the required entry point at the template root (e.g. <profile>\webview-ui\default\index.html). <template> defaults to default and can be managed / switched from the component's preferences page. The legacy location <component dir>\foo_ui_webview2_resources\dist\ is still supported for backward compatibility. Restart foobar2000 to load it. You can build custom themes on top of sdk/ (foo-webview-sdk).
Choose your path
- Coming from Spider Monkey Panel / JScript? The SMP compatibility layer maps 35 SMP callbacks (
on_playback_new_track, …) and shipsfb/plmanwrapper objects, so existing knowledge and much existing code carry over. → SMP compatibility docs - Web developer?
npm install foo-webview-sdkgives you typedfb.*wrappers and Web Components, and you can point the component at your Vite/webpack dev server (window.setDevServerConfig) for hot reload against the live player. → SDK quickstart - Rather not write code by hand? Point an AI agent at the MCP server (
npx foo-ui-webview2-mcp): it can control playback and playlists, read player state, and take screenshots over CDP — enough for an agent to build and iterate a theme together with you. → MCP docs
npm Packages
The two JavaScript packages below are published to npm and can be installed directly (no source build required):
| Package | Install / Use | Description |
|---|---|---|
foo-webview-sdk |
npm install foo-webview-sdk |
Theme / frontend SDK (Bridge API + Web Components + SMP compatibility layer), see sdk/ |
foo-ui-webview2-mcp |
npx foo-ui-webview2-mcp |
MCP Server for AI agents to drive foobar2000 over CDP, see mcp/ |
API Overview
200+ APIs span the following namespaces:
playback, playlist, library, window, config, file, dialog, clipboard, shell, http, keyboard, ui, lyrics, metadata, audio, console, dnd, queue, discovery, replaygain, playcount, titleformat, selection, port
Events (colon format)
playback:trackChanged, playback:paused, playback:stopped, playback:seeked,
playback:volumeChanged, playback:time, playlist:itemsAdded, playlist:itemsRemoved,
playlist:activated, playlist:created, playlist:removed, playlist:renamed,
playlist:selectionChanged, metadb:changed, plugin:registered, api:registered
Usage Example
// invoke uses dot format
const track = await fb2k.invoke('playback.getCurrentTrack');
const results = await fb2k.invoke('library.search', { query: 'artist:Radiohead' });
// event listeners use colon format
fb2k.on('playback:trackChanged', (track) => { /* ... */ });
Plugin Extensions
Other foobar2000 plugins can register APIs through PluginRegistry for the frontend to call:
#include "api/PluginRegistry.h"
void RegisterMyApis() {
auto& registry = PluginRegistry::GetInstance();
registry.RegisterPlugin("my_plugin", "My Plugin", "1.0.0", "Author", "Description");
registry.RegisterExternalApi("my_plugin", "doSomething",
[](const json& params) -> json {
return {{"result", "done"}};
},
"Perform an operation"
);
}
const result = await fb2k.invoke('my_plugin.doSomething', { param1: 'value' });
Security Restrictions
Threat model. This is a dedicated, domain-specific UI host for foobar2000 — themes come from you or trusted sources, so installing a theme carries the same trust as installing any foobar2000 component. The goal is therefore fail-safe (stop a buggy theme from accidentally harming the system), not sandboxing untrusted code; over-locking-down such a specialized component would only tie its own hands. The real guardrails are path validation and protocol checks:
| API | Restriction |
|---|---|
| shell.exec / shell.spawn | No command / executable allowlist — commands run as given; cwd and absolute paths are validated by PathSecurity (trusts the theme author; this is not a sandbox) |
| shell.openWith | Blocklist — opening 29 executable / script extensions (.exe, .bat, .ps1, .dll, .lnk, …) is refused |
| file.read/write | Path restrictions — system directories (C:\Windows, C:\Program Files, C:\ProgramData) are inaccessible; writes are limited to the foobar2000 config dir and %TEMP% |
| http.get/post | SSRF protection — localhost / private / link-local addresses are blocked (including post-DNS-resolution checks against rebinding) |
| CDP remote debugging | Off by default — must be enabled manually, bound to localhost only |
Full details: security notes and permissions reference.
Building from Source
You only need this section to develop the component itself. Users install the packaged
.fb2k-component— see Quick start above.
Requirements
- Visual Studio 2022 (17.8+), v145 toolset
- Windows SDK 10.0.22621+
- WebView2 Runtime
- Node.js 18+ (to build the SDK / MCP / docs site)
C++ Component
# Standard build
.\build.ps1 -Config Release -Platform x64
# Package .fb2k-component (x86 + x64)
.\build-package.ps1
# Package offline documentation (Windows users need no extra runtime)
.\build-docs-package.ps1
The documentation ZIP opens through open-docs.cmd and uses only Windows 10/11 built-in Windows PowerShell 5.1, .NET Framework, and the default browser. It does not require Node.js, Python, npm, administrator access, or an Internet connection.
TypeScript SDK (build from source, for development)
Consumers do not need to build it — just
npm install foo-webview-sdk(see "npm Packages" above).
cd sdk
npm run build
MCP Server (build from source, for development)
Consumers do not need to build it — just
npx foo-ui-webview2-mcp(see "npm Packages" above).
cd mcp
npm install
npm run build
Tech Stack
| Layer | Technology |
|---|---|
| C++ component | C++20, VS 2022 (v145), Windows SDK 10.0 |
| WebView2 | Microsoft.Web.WebView2 1.0.3719.77 (NuGet) |
| WIL | Microsoft.Windows.ImplementationLibrary 1.0.240803.1 |
| JSON | nlohmann/json |
| foobar2000 | SDK v2.0+ (lib/) |
| Columns UI | SDK (git submodule: lib/columns_ui-sdk) |
| TypeScript SDK | foo-webview-sdk (sdk/, MIT, tsup) |
| MCP Server | foo-ui-webview2-mcp (mcp/, Node.js 18+) |
Project Structure
foo_ui_webview2/
├── src/ # C++ source code
│ ├── core/ # WebView core, UserInterface, etc.
│ ├── window/ # MainWindow, PopupWindow, WindowManager
│ ├── webview/ # WebView host and environment
│ ├── api/ # BridgeCore + API handlers
│ ├── callbacks/ # foobar2000 SDK event callbacks
│ ├── panels/ # DUI/CUI panel integration
│ ├── selection/ # Selection tracking
│ ├── interfaces/ # Service abstractions
│ └── utils/ # Utility functions
├── sdk/ # TypeScript SDK (foo-webview-sdk)
│ ├── src/ # Source (bridge/, components/, smp/, types/)
│ └── package.json
├── mcp/ # MCP Server (AI agent CDP bridge)
│ ├── src/ # TypeScript source
│ └── tests/ # Unit + E2E tests
├── tests/ # C++ unit tests (GoogleTest)
├── docs/vitepress/ # User documentation site
├── lib/ # Third-party libraries
│ ├── foobar2000_sdk/ # foobar2000 SDK (BSD)
│ ├── columns_ui-sdk/ # Columns UI SDK (submodule)
│ └── json/ # nlohmann/json (MIT)
├── build.ps1 # Standard build script
├── build-package.ps1 # .fb2k-component packaging
├── foo_ui_webview2.sln # VS solution
├── foo_ui_webview2.vcxproj # VS project file
└── packages.config # NuGet package config
License
The main component of this project is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later); see LICENSE for the full terms.
- Main component: GPL-3.0-or-later
- TypeScript SDK (
sdk/): MIT License (seesdk/LICENSE)
Third-party libraries retain their own licenses: foobar2000 SDK (BSD), pfc / libPPUI (zlib), nlohmann/json (MIT), Columns UI SDK.
No comments yet
Be the first to share your take.