VS Code in the Home: local installation and font customization without sudo
Published on 17 April 2026
Why install VS Code in`/opt`or via`apt`when you can place it in your home and turn your IDE into a playground without ever typing`sudo`? Here is the account of a local installation followed by a fierce battle to enlarge the fonts of the menu and the file explorer.
- toc
-
[]
Journey Overview
The Why: VS Code in the Home
The problem with system installation
VS Code installed via`apt`, dnf`or in/opt`locks the application files behind root rights. Any modification of the native CSS,product.json`or the installation folder requires`sudo.
However, when usingopencode(CLI tool to drive an LLM on one’s code), the agent needs to be able to:
-
Write to configuration files (
~/.config/Code/User/settings.json) — that is already in the home -
Modify the IDE assets (workbench CSS,
product.json) for advanced customizations — that is blocked without sudo
The solution: a local installation
We download the official tarball archive and extract it directly into`~/apps/`:
mkdir -p ~/apps
cd ~/apps
wget "https://code.visualstudio.com/sha/download?build=stable&os=linux-x64" -O vscode.tar.gz
tar -xzf vscode.tar.gz
rm vscode.tar.gz
The binary is then located in`~/apps/VSCode-linux-x64/bin/code`. No`sudo`is necessary to read, modify, or replace any file under`~/apps/VSCode-linux-x64/`.
Concrete Advantages
| Advantage | Detail |
|---|---|
No sudo |
All IDE files belong to the user |
Direct CSS modification |
We can patch`workbench.desktop.main.css`without elevation of privileges |
Home-made update script |
A simple shell script automatically downloads, replaces, and repatches |
Isolation |
The system installation is not polluted; rollback = delete the folder |
Customizing the main menu font
The observation
The default font of the main menu (File, Edit, View…) and the dropdowns is too small. VS Code offers no setting to modify it.
The technique: direct CSS patch
We add CSS to the end of the file`workbench.desktop.main.css`:
CSS_FILE="$HOME/apps/VSCode-linux-x64/resources/app/out/vs/workbench/workbench.desktop.main.css"
cat >> "$CSS_FILE" << 'EOF'
.menubar-menu-title{font-size:23px!important}
.menubar>.menubar-menu-button{font-size:23px!important}
.monaco-menu-option{font-size:22px!important;line-height:34px!important}
.monaco-menu .action-label:not(.codicon){font-size:22px!important}
.menubar-menu-items-holder .monaco-menu .action-item .action-label{font-size:22px!important}
EOF
Removing the integrity warning
VS Code detects modifications to its files and displays a "Your installation is corrupt" banner. To avoid this, we remove the checksums from`product.json`:
import json
product_json = "$HOME/apps/VSCode-linux-x64/resources/app/product.json"
with open(product_json, 'r') as f:
data = json.load(f)
data.pop('checksums', None)
with open(product_json, 'w') as f:
json.dump(data, f, indent=2)
After restarting, no more warnings and the menus are finally readable.
Customizing the Explorer pane font — the struggle
Attempt 1: a setting that doesn’t exist
We first try the native setting`workbench.tree.fontSize`in`settings.json`:
{
"workbench.tree.fontSize": 20
}
Result:no effect. This setting does not exist in VS Code. Proof that unrecognized settings are silently ignored.
Attempt 2: the Custom CSS and JS Loader extension
We install the extension`be5invis.vscode-custom-css`:
~/apps/VSCode-linux-x64/bin/code --install-extension be5invis.vscode-custom-css
We create a CSS file in`~/.vscode-custom-css/custom.css`with selectors targeting the explorer elements:
.monaco-tree-rows .monaco-tree-row,
.sidebar .monaco-list-row,
.explorer-viewlet .monaco-list-row,
.monaco-list-row .monaco-icon-label {
font-size: 22px !important;
line-height: 36px !important;
}
And we reference this file in the settings:
{
"vscode_custom_css.imports": [
"file:///home/user/.vscode-custom-css/custom.css"
]
}
Result:the changes are not applied.
The trap: the extension must be activated every time
The extension documentation is discreet on this crucial point: after each modification of the custom CSS, youmustexecute the command from the palette:
-
Ctrl+Shift+P→ type"Enable Custom CSS and JS" -
VS Code asks for a restart → accept
Without this step, the CSS is never injected into the IDE.
Attempt 3: lines overlap
Even with`font-size: 22px` et line-height: 36px, descending letters (g, p, f, b) overflow into neighboring lines. We try adding`height` et min-height:
.monaco-list-row {
height: 36px !important;
min-height: 36px !important;
}
Result:no change. VS Code calculates line heights in JavaScript and overrides CSS values.
The solution: zoom on the parent container
Rather than fighting the JavaScript layout, we use the`zoom`property on the lines container:
.explorer-viewlet .monaco-list-rows,
.sidebar .monaco-list-rows {
zoom: 1.25;
}
`zoom`uniformly enlarges the rendering of the container — text AND spacing — without breaking the layout calculated by the VS Code JavaScript engine. The 1.25 factor corresponds roughly to moving from 13px to 16px.
Result:file names are finally readable, lines correctly spaced.
Summary of selectors and what works
| Approach | CSS | Result |
|---|---|---|
|
|
Larger text but overlapping lines |
|
|
No effect (JS override) |
|
|
Success — proportional text + spacing |
The automatic update script
The problem
When VS Code updates, it replaces the installation folder anderases all CSS patches. Modifications must be re-applied manually each time.
The vscode-update.sh script
We create`~/apps/vscode-update.sh`:
#!/bin/bash
set -e
VSCODE_DIR="$HOME/apps/VSCode-linux-x64"
BACKUP_DIR="$HOME/apps/vscode-backup"
TEMP_DIR="/tmp/vscode-update"
MENUBAR_FONT_SIZE="23px"
DROPDOWN_FONT_SIZE="22px"
echo "=== VS Code Local Updater ==="
CURRENT_VERSION=$("$VSCODE_DIR/bin/code" --version 2>/dev/null | head -1)
echo "Current version: $CURRENT_VERSION"
echo "Downloading latest VS Code..."
mkdir -p "$TEMP_DIR"
wget -q "https://code.visualstudio.com/sha/download?build=stable&os=linux-x64" \
-O "$TEMP_DIR/vscode.tar.gz"
echo "Extracting..."
mkdir -p "$TEMP_DIR/extracted"
tar -xzf "$TEMP_DIR/vscode.tar.gz" -C "$TEMP_DIR/extracted"
NEW_VERSION=$("$TEMP_DIR/extracted/VSCode-linux-x64/bin/code" \
--version 2>/dev/null | head -1)
echo "New version: $NEW_VERSION"
if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
echo "Already up to date!"
rm -rf "$TEMP_DIR"
exit 0
fi
echo "Backing up current installation..."
mkdir -p "$BACKUP_DIR"
cp -r "$VSCODE_DIR" "$BACKUP_DIR/VSCode-linux-x64-$(date +%Y%m%d-%H%M%S)"
echo "Updating..."
rm -rf "$VSCODE_DIR"
mv "$TEMP_DIR/extracted/VSCode-linux-x64" "$VSCODE_DIR"
rm -rf "$TEMP_DIR"
CSS_FILE="$VSCODE_DIR/resources/app/out/vs/workbench/workbench.desktop.main.css"
echo "Re-applying custom CSS patch \
(menubar=${MENUBAR_FONT_SIZE}, dropdown=${DROPDOWN_FONT_SIZE})..."
cat >> "$CSS_FILE" << CSSEOF
.menubar-menu-title{font-size:${MENUBAR_FONT_SIZE}!important}\
.menubar>.menubar-menu-button{font-size:${MENUBAR_FONT_SIZE}!important}\
.monaco-menu-option{font-size:${DROPDOWN_FONT_SIZE}!important;\
line-height:34px!important}\
.monaco-menu .action-label:not(.codicon)\
{font-size:${DROPDOWN_FONT_SIZE}!important}\
.menubar-menu-items-holder .monaco-menu .action-item .action-label\
{font-size:${DROPDOWN_FONT_SIZE}!important}
CSSEOF
PRODUCT_JSON="$VSCODE_DIR/resources/app/product.json"
if [ -f "$PRODUCT_JSON" ]; then
echo "Removing checksums to prevent integrity warning..."
python3 -c "
import json
with open('$PRODUCT_JSON','r') as f: data=json.load(f)
data.pop('checksums', None)
with open('$PRODUCT_JSON','w') as f: json.dump(data,f,indent=2)
print('Done.')
"
fi
echo "=== Update complete: $CURRENT_VERSION -> $NEW_VERSION ==="
The script:
-
Downloads the latest stable version
-
Checks if the version differs from the current one
-
Backs up the current installation (timestamped) in`~/apps/vscode-backup/`
-
Replaces the installation folder
-
Re-appliesthe main menu CSS patch
-
Deletes the checksums de `product.json`to avoid the integrity warning
| Explorer pane customizations via the Custom CSS extension and the file`~/.vscode-custom-css/custom.css`survive updates because they live outside the installation folder. |
Files involved — overview
| Path | Role | Survives updates? |
|---|---|---|
|
IDE Installation |
No (replaced) |
|
Workbench CSS (menu, dropdowns) |
No (re-patched by the script) |
|
Integrity checksums |
No (re-cleaned by the script) |
|
Automatic update script |
Yes |
|
User settings (fontSize, custom CSS) |
Yes |
|
Custom CSS for the Explorer (zoom) |
Yes |
Lessons Learned
Installing in the home frees everything
A local installation in`~/apps`gives total control over VS Code:
-
No`sudo`to modify the CSS or configuration
-
The opencode+LLM agent can write to config files and IDE assets
-
Trivial rollback: restore the timestamped backup
zoom > font-size for list components
VS Code controls line height via JavaScript. Modifying`font-size`without being able to touch the height allocated by the layout engine results in overflowing text. The`zoom`property on the parent container enlarges everything proportionally and bypasses this problem.
Custom CSS extension requires explicit activation
It is not a "set and forget" setting. Every modification to the custom CSS file requires re-executing "Enable Custom CSS and JS" from the command palette (Ctrl+Shift+P).
An update script is indispensable
Without a script, every VS Code update erases the workbench CSS patches. The`vscode-update.sh`script automates downloading, replacing, re-patching, and cleaning checksums.
Quick References
-
VS Code Download: https://code.visualstudio.com/Download
-
Custom CSS and JS Loader Extension:`be5invis.vscode-custom-css`
-
VS Code issue requesting a native setting for the Explorer font:https://github.com/microsoft/vscode/issues/149[github.com/microsoft/vscode#149]