Creating a VSCode Extension to Display a Background Video
This article explains how to develop a VSCode extension that injects a video element into the editor’s workbench, allowing users to set a dynamic background video (such as the Wukong promotional clip), with configurable opacity, video selection, installation, and uninstallation instructions.
Background: The author discovered that VSCode cannot natively play videos and created a plugin that sets the "Black Myth: Wukong" promotional video as the editor background, producing a striking visual effect.
Effect Demonstration: Two theme examples are shown with animated GIFs illustrating the video background in action.
Usage Instructions: Install the extension named wukong-background-video from the VSCode Marketplace (or search locally). After installation, restart VSCode to see the video. A warning about a corrupted file can be ignored because the extension modifies VSCode source. To uninstall, run the command background-video.uninstall from the command palette, then remove the extension and restart. In the settings, search for background-video to adjust opacity (0‑1) and select the video (video1.mp4 or video2.mp4). The built‑in videos are sourced from https://www.wegame.com.cn/wukong. To use custom videos, replace the files in the VSCode installation directory (e.g., on macOS: /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench ).
Plugin Development Process – Principle: VSCode is built with Electron, so its UI is HTML/JS. The extension injects a small JavaScript snippet into workbench.js that creates a video element, sets its style (full‑screen, loop, muted, opacity, etc.), and appends it to the document body. This can be done either by a script that patches the source or by an extension that performs the injection at runtime; the author chose the extension approach for easier distribution.
Implementation – Creating the Extension Project:
yo codeCore Extension Code (simplified):
const vscode = require('vscode');
const path = require('path');
const { readFileSync, writeFileSync, copyFileSync, unlinkSync } = require('fs');
function activate(context) {
let config = vscode.workspace.getConfiguration('background-video');
const opacity = config.get('opacity');
const videoName = config.get('videoName');
const workbenchDirPath = path.join(path.dirname(require.main.filename), 'vs', 'code', 'electron-sandbox', 'workbench');
const workbenchFilePath = path.join(workbenchDirPath, 'workbench.js');
const jsPath = path.resolve(context.extensionPath, 'resources/main.js');
const video1Path = path.resolve(context.extensionPath, 'resources/video1.mp4');
const video2Path = path.resolve(context.extensionPath, 'resources/video2.mp4');
function setContent(opacity = 0.4, videoName = 'video1.mp4') {
let jsCode = readFileSync(jsPath, 'utf8').toString();
jsCode = jsCode.replace('{opacity}', opacity ? +opacity : 0.4);
jsCode = jsCode.replace('{videoName}', videoName);
let workbenchCode = readFileSync(workbenchFilePath, 'utf8').toString();
const re = new RegExp("\/\*background-video-start\*\/[\s\S]*?\/\*background-video-end\*\/", 'g');
workbenchCode = workbenchCode.replace(re, '').replace(/\s*$/,'');
writeFileSync(workbenchFilePath, `${workbenchCode}\n/*background-video-start*/\n${jsCode}\n/*background-video-end*/`);
copyFileSync(video1Path, path.join(workbenchDirPath, 'video1.mp4'));
copyFileSync(video2Path, path.join(workbenchDirPath, 'video2.mp4'));
}
setContent(opacity, videoName);
vscode.workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration('background-video.opacity') || event.affectsConfiguration('background-video.videoName')) {
const cfg = vscode.workspace.getConfiguration('background-video');
setContent(cfg.get('opacity'), cfg.get('videoName'));
vscode.window.showInformationMessage('Configuration updated, restart VSCode to apply.');
}
});
context.subscriptions.push(vscode.commands.registerCommand('background-video.uninstall', () => {
let workbenchCode = readFileSync(workbenchFilePath, 'utf8').toString();
const re = new RegExp("\/\*background-video-start\*\/[\s\S]*?\/\*background-video-end\*\/", 'g');
workbenchCode = workbenchCode.replace(re, '').replace(/\s*$/,'');
writeFileSync(workbenchFilePath, workbenchCode);
unlinkSync(path.join(workbenchDirPath, 'video1.mp4'));
unlinkSync(path.join(workbenchDirPath, 'video2.mp4'));
vscode.window.showInformationMessage('Content removed, you can now uninstall the extension.');
}));
}
function deactivate() {}
module.exports = { activate, deactivate };Injected JavaScript (resources/main.js) that creates the video element:
var video = document.createElement('video');
video.src = "{videoName}";
video.style.width = '100vw';
video.style.height = '100vh';
video.loop = true;
video.autoplay = true;
video.muted = true;
video.style.position = 'absolute';
video.style.top = 0;
video.style.left = 0;
video.style.zIndex = 100;
video.style.opacity = {opacity};
video.style.pointerEvents = 'none';
video.style.objectFit = "fill";
document.body.appendChild(video);Effect: After installing the extension, the injected JavaScript appears in workbench.js and the two video files are copied into the workbench directory, resulting in the background video being displayed inside VSCode.
Conclusion: Users are encouraged to submit pull requests for new ideas, and the source code is hosted at https://github.com/dbfu/wukong-background-video .
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.