Custom UI Style is a VSCode extension that allows you to customize the editor's appearance and behavior by injecting custom CSS and JavaScript. You can unify the global font family, set a background image, modify Electron BrowserWindow
options, add your own custom styles and scripts, and even patch files in other VSCode extensions.
- Works with VSCode 1.103! (Tested on Windows and MacOS)
Warning
This extension works by modifying the VSCode's source css and js files.
Untested on Linux and VSCode forks (like Cursor, WindSurf, etc.), and I currently lack the energy to adapt them. If this extension causes issues in your editor, please consider using these more mature alternative extensions
- Unify the global font family for the editor and webviews.
- Set a background image for the editor window.
- Apply custom stylesheets to both the editor and webviews.
- Configure Electron
BrowserWindow
options. - Support for restarting VSCode to apply changes.
- Suppress the "Your Code installation is corrupt" message.
- Load external CSS and JavaScript files.
- Patch files in other extensions.
- Backup: When you first install the extension or after a VSCode update, you'll be prompted to create a backup of the original files. This is important for rollback.
- Configure: Add your customizations to your
settings.json
file. See the Example and Configurations sections for details. - Apply: Open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P) and run
Custom UI Style: Reload
to apply your changes. - Rollback: To revert all changes and restore the original VSCode files, run
Custom UI Style: Rollback
from the Command Palette.
See details for more information.
Available CSS Variables:
--cus-monospace-font
: Target monospace font family--cus-sans-font
: Target sans-serif font family
Starting from v0.4.2, you can load external CSS and JavaScript files from local or remote URLs.
Caution
Loading external resources can introduce security risks or cause runtime crashes. Use this feature with caution.
- All resources are applied to the editor, not webviews.
- Resources are fetched and merged during reload. Live-watching of files is not supported.
{
"custom-ui-style.external.imports": [
// assume the script is ESM format
"file://D:/data/test.js",
"file:///Users/yourname/test.js",
// Variable supports:
// Load from user home dir
"file://${userHome}/test.css",
// Load from environment variable (with optional fallback value)
"file://${env:your_env_name:optional_fallback_value}/other.js",
// Remote resources will be downloaded
{
// <link rel="stylesheet" href="./external.css"></link>
// will load before `custom-ui-style.stylesheet`
"type": "css",
"url": "https://fonts.googleapis.com/css?family=Sofia",
},
{
// <script src="./external.js"></script>
"type": "js",
"url": "https://example.com/test.js",
},
{
// <script src="./external.module.js" type="module"></script>
"type": "js-module",
"url": "https://example.com/test.module.js",
}
]
}
By default, all resources are re-fetched on every reload, and failed fetches are skipped.
To cache resources and avoid re-fetching when custom-ui-style.external.imports
is unchanged, set the load strategy to "cache"
:
{
"custom-ui-style.external.loadStrategy": "cache"
}
To disable all external resources, set the load strategy to "disable"
:
{
"custom-ui-style.external.loadStrategy": "disable"
}
Find and replace target string or Regexp
in extension's file
{
// "custom-ui-style.extensions.enable": false,
"custom-ui-style.extensions.config": {
// extension id
"github.copilot-chat": [
{
// target file path related to extension root
"filePath": "dist/extension.js",
// find string (support JavaScript like regexp)
"find": "https://generativelanguage.googleapis.com/v1beta/openai",
// replace string
"replace": "<path/to/url>"
}
]
},
}
This extension modifies files in your VSCode installation directory. All modified files are backed up with a .custom-ui-style
suffix in the same directory. You can see the full list of modified files in path.ts
.
When you reload the configuration, the extension restores the original files from the backup, applies your custom patches, and then reloads the window or restarts the application.
If your changes don't seem to apply, you may need to fully restart VSCode.
- Windows/Linux: Close all VSCode windows and restart the application.
- macOS: Press Command + Q to quit the application, then restart it.
There are also a guide and a video (macOS) available for more detailed instructions.
If you see this error, it means VSCode is installed on a read-only filesystem (e.g., via Snap or AppImage). This extension needs to write to the installation directory, so you'll need to install VSCode using a different method.
This error can occur due to system permission restrictions. To fix it, you need to change the ownership of the VSCode installation directory.
First, fully close VSCode (Command + Q</_kbd> on macOS). Then, run the following command:
# macOS
sudo chown -R $(whoami) "/Applications/Visual Studio Code.app"
# Linux
sudo chown -R $(whoami) "/usr/local/code"
See #6 for more details.
In some VSCode forks like Cursor, the extension detail panel may not render due to a Content Security Policy (CSP) violation. To work around this, you can disable the webview patch:
{
"custom-ui-style.webview.enable": false
}
Key | Description | Type | Default |
---|---|---|---|
custom-ui-style.preferRestart |
Prefer restarting VSCode after updates (always true for VSCode >= 1.95.0) | boolean |
false |
custom-ui-style.reloadWithoutPrompting |
Reload/restart immediately without a notification prompt | boolean |
false |
custom-ui-style.watch |
Automatically reload window on configuration changes (ignores imports) | boolean |
true |
custom-ui-style.electron |
Electron BrowserWindow options (see Electron documentation) | object |
{} |
custom-ui-style.font.monospace |
Global monospace font family for editor and webviews (falls back to editor's font) | string |
`` |
custom-ui-style.font.sansSerif |
Global sans-serif font family for editor and webviews | string |
`` |
custom-ui-style.background.url |
Full-screen background image URL (e.g., 'https://', 'file://', 'data:') - not synced | string |
`` |
custom-ui-style.background.syncURL |
Full-screen background image URL (synced), supports variables like ${userHome} or ${env:VAR:fallback}. Lower priority than 'url'. | string |
`` |
custom-ui-style.background.opacity |
Background image opacity (0 to 1) | number |
0.9 |
custom-ui-style.background.size |
Background image size (e.g., 'cover', 'contain') | string |
"cover" |
custom-ui-style.background.position |
Background image position | string |
"center" |
custom-ui-style.external.loadStrategy |
Strategy for loading external CSS or JS resources | string |
"refetch" |
custom-ui-style.external.imports |
External CSS or JS resources; supports variables (${userHome}, ${env:VAR:fallback}) and protocols ('https://', 'file://') | array |
`` |
custom-ui-style.stylesheet |
Custom CSS for the editor; supports nested selectors | object |
{} |
custom-ui-style.extensions.enable |
Enable file patching in other extensions | boolean |
true |
custom-ui-style.extensions.config |
Configuration for patching extension files (key: extension ID, value: patch config) | object |
{} |
custom-ui-style.webview.enable |
Enable style patching in webviews | boolean |
true |
custom-ui-style.webview.removeCSP |
Remove Content-Security-Policy restrictions in webviews | boolean |
true |
custom-ui-style.webview.monospaceSelector |
Custom monospace selector for webviews | array |
`` |
custom-ui-style.webview.sansSerifSelector |
Custom sans-serif selector for webviews | array |
`` |
custom-ui-style.webview.stylesheet |
Custom CSS for webviews; supports nested selectors | object |
{} |
Command | Title |
---|---|
custom-ui-style.reload |
Custom UI Style: Reload |
custom-ui-style.rollback |
Custom UI Style: Rollback |
- APC for my previous usage
- Background for my previous usage
- vscode-sync-settings for fully restart logic
- vscode-fix-checksums for checksum patch logic (Prevent corrupt warning notice on startup)
- Custom CSS and JS Loader for external resource logic
MIT