Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisit VS Code folder structure for app data, settings, extensions #3884

Open
Tyriar opened this issue Mar 8, 2016 · 205 comments
Open

Revisit VS Code folder structure for app data, settings, extensions #3884

Tyriar opened this issue Mar 8, 2016 · 205 comments
Labels
debt Code quality issues feature-request Request for new features or functionality workbench-os-integration Native OS integration issues
Milestone

Comments

@Tyriar
Copy link
Member

Tyriar commented Mar 8, 2016

Config is stored in ~/.config/Code[ - <quality>]/User. To match platform conventions (lowercase and hyphens for everything) as well as to keep consistency with the cli code[-<quality>] I propose we change the settings directory one of:

If we moved this it would probably require some discovery/migration on first launch of a newer version.


The below is a living document.

Proposed folder structure

Notes:

  • I don't think we should be encouraging the use of admin rights within vscode, instead a permissions elevation dialog would probably be better than allowing a specific place for root user data Use specific user data directories when running as root #5561
  • I want to clean up the whole code vs vscode thing in this change; only official builds should carry the visual studio branding, that should carry over to the config directories consistently as well.
  • The CLI args --user-data-dir and --extensions-dir will need to be adjusted for this, something like --config-dir and --cache-dir would probably be better.

Windows

Old

Settings:                %APPDATA%\Code[ - Variant]\User\settings.json
Keybindings:             %APPDATA%\Code[ - Variant]\User\keybindings.json
Snippets:                %APPDATA%\Code[ - Variant]\User\snippets\
Workspace storage:       %APPDATA%\Code[ - Variant]\User\workspaceStorage\
Chromium user data:      %APPDATA%\Code[ - Variant]\
Extensions:              %USERPROFILE%\.vscode[-variant]\extensions\

New

Settings:                %APPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\settings.json
Keybindings:             %APPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\keybindings.json
Snippets:                %APPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\snippets\
Workspace storage:       %LOCALAPPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\workspaceStorage\
Chromium user data:      %LOCALAPPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\userdata\
Extensions:              %LOCALAPPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\extensions\

Notes:

  • Note that %APPDATA% is roaming and %LOCALAPPDATA% is local, meaning extensions will not be carried across multiple machines until a solution is devised for Persist an extensions manifest file #15442. An extension manifest, eg. %APPDATA%\Microsoft\[Visual Studio ]Code[ - Variant]\extensions.json which automatically installs extensions is my thinking of solving this problem.

Linux

Old

Settings:                $HOME/.config/Code[ - Variant]/User/settings.json
Keybindings:             $HOME/.config/Code[ - Variant]/User/keybindings.json
Snippets:                $HOME/.config/Code[ - Variant]/User/snippets/
Workspace storage:       $HOME/.config/Code[ - Variant]/User/workspaceStorage/
Chromium user data:      $HOME/.config/Code[ - Variant]/
Extensions:              $HOME/.vscode[-variant]/extensions/ (not moving)

New

Settings:                $XDG_CONFIG_HOME/[vs]code[-variant]/settings.json
Keybindings:             $XDG_CONFIG_HOME/[vs]code[-variant]/keybindings.json
Snippets:                $XDG_CONFIG_HOME/[vs]code[-variant]/snippets/
Workspace storage:       $XDG_CACHE_HOME/[vs]code[-variant]/workspaceStorage/
Chromium user data:      $XDG_CACHE_HOME/[vs]code[-variant]/userdata/
Extensions:              $XDG_CACHE_HOME/[vs]code[-variant]/extensions/

Notes:

Mac

Old

Settings:                $HOME/Library/Application Support/Code[ - Variant]/User/settings.json
Keybindings:             $HOME/Library/Application Support/Code[ - Variant]/User/keybindings.json
Snippets:                $HOME/Library/Application Support/Code[ - Variant]/User/snippets/
Workspace storage:       $HOME/Library/Application Support/Code[ - Variant]/User/workspaceStorage/
Chromium user data:      $HOME/Library/Application Support/Code[ - Variant]/
Extensions:              $HOME/.vscode[-variant]/extensions/ (not moving)

New

Settings:                $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/settings.json
Keybindings:             $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/keybindings.json
Snippets:                $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/snippets/
Workspace storage:       $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/workspaceStorage/
Chromium user data:      $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/userdata/
Extensions:              $HOME/Library/Application Support/[Visual Studio ]Code[ - Variant]/extensions/

Notes:

@Tyriar Tyriar added debt Code quality issues linux Issues with VS Code on Linux labels Mar 8, 2016
@bpasero bpasero changed the title Code .config on Linux doesn't follow OS conventions Revisit VS Code folder structure for app data, settings, extensions Mar 9, 2016
@bpasero bpasero added this to the March 2016 milestone Mar 9, 2016
@bpasero
Copy link
Member

bpasero commented Mar 9, 2016

I wonder if we should do this before GA. Besides the summary, I also do not like that we have 2 folders, one for application data and one for extensions. Ideally we have one folder for both.

@Tyriar
Copy link
Member Author

Tyriar commented Mar 9, 2016

It was a little confusing when I was writing my script that automates my config to discover there were 2 config folders. If this is going to be done I vote for ~/.code[-<quality>] so that it matches the executable name.

@bpasero
Copy link
Member

bpasero commented Mar 9, 2016

I am more worried about the migration than finding a name :)

@felixfbecker
Copy link
Contributor

I also don't get why there are two folders. Afaik .vscode only includes one subfolder, extensions. Why not simply put settings in .vscode aswell?

I also like .vscode more than .code, Visual Studio stuff is also in .vs and it is less ambiguous.

@Tyriar
Copy link
Member Author

Tyriar commented Mar 11, 2016

While fiddling with the config directories it might be worth tackling a portable version at the same time #329

@bpasero bpasero modified the milestones: Backlog, March 2016 Mar 11, 2016
@bpasero
Copy link
Member

bpasero commented Mar 11, 2016

Not for GA.

@bpasero
Copy link
Member

bpasero commented Mar 13, 2016

Btw the largest chunk of stuff in app date is created by Chrome itself and is used for local storage, index db, etc. It would be easy to migrate and move our settings out of that folder, I am worried about migrating the rest...

@bpasero bpasero modified the milestones: April 2016, Backlog Mar 14, 2016
@bpasero bpasero modified the milestones: Backlog, April 2016 Mar 30, 2016
@Tyriar
Copy link
Member Author

Tyriar commented Apr 20, 2016

@bpasero what are your thoughts on getting this in for April? My experience with playing around with user data to date is that it seems fairly contained and can be moved without any issues.

The reason I want to do this soon is I'd like to have a set root user data dir as one is required to run under sudo (#5561). That would mean that instead of:

  • ~/.vscode
  • ~/.config/Code
  • ~/.config/Code-Root

We could have

  • ~/.vscode
  • ~/.vscode/user-data
  • ~/.vscode/user-data-root

For migration something like this should work in main.js:

if the regular config dir does not exists
  if the old config dir does exist
    copy the old config dir to the new location

Tyriar added a commit that referenced this issue Apr 20, 2016
Permanently move the user data to a sub-folder of the config directory for the
current variant of code. For example:

- ~/.config/Code -> ~/.vscode/user-data
- ~/.config/Code\ -\ OSS -> ~/.vscode-oss/user-data
- ~/.config/Code-Development -> ~/.vscode-oss-dev/user-data

Fixes #3884
@bpasero
Copy link
Member

bpasero commented Apr 21, 2016

@Tyriar happy to accept a PR on such a change and migration.

@bpasero
Copy link
Member

bpasero commented Apr 21, 2016

@Tyriar ah nice, did not see your PR until now!

@bpasero bpasero modified the milestones: April 2016, Backlog, May 2016 Apr 21, 2016
@bpasero
Copy link
Member

bpasero commented Apr 21, 2016

Given my feedback, I am not suggesting to do this so late in the milestone.

@TomaszGasior
Copy link

@wc7086 Please stop writing comments like that — this does not provide any value to solve the problem, and all the people subscribed to the topic need to get notification about that.

@metov
Copy link

metov commented Apr 19, 2023

@TomaszGasior What do you suggest people should do to increase the chances that this will be fixed?

@realitymolder
Copy link

@TomaszGasior What do you suggest people should do to increase the chances that this will be fixed?

True.
@TomaszGasior maybe some people don't understand that clear enough, but clearly some of the users of this app/ project (& there are several issues regarding this issue and its consequences. Even recently! #179774) are hurting and suffering from this continuous flaw.
I think that as developers, it is our duty to report and change this reality. Especially in one, if not, the most popular IDEs today.

@ZerdoX-x
Copy link

Anyways bumping won`t get the issue resolved faster. I would like to get notifications about the progress, not about amount of people who discover it. I guess I will unsubscribe from this issue because github zoomers don't understand what tickets are.

@RokeJulianLockhart
Copy link

@ZerdoX-x, you can subscribe to whether the issue is closed or reopened rather than unsubscribe entirely.

@BrianL-STCU
Copy link

BrianL-STCU commented Aug 23, 2023

Currently, VSCode alone stores a total of 1.6 GiB of just cache data in my roaming profile, making the morning login over my slow DSL connection extremely time-consuming.

Path                                                                                                          Size    DirectorySize DirectorySizeOnDisk
----                                                                                                          ----    ------------- -------------------
c:\users\username\appdata\roaming\code\cacheddata                                                             503.2MB     527598178           544657408
c:\users\username\appdata\roaming\code\cachedextensionvsixs                                                   478.7MB     502000711           502038528
c:\users\username\appdata\roaming\code\cache                                                                  319.8MB     335383278           336080896
c:\users\username\appdata\roaming\code\cache\cache_data                                                       319.8MB     335383278           336076800
c:\users\username\appdata\roaming\code\service worker\cachestorage                                            47.5MB       49801653            56680448
c:\users\username\appdata\roaming\code\cachedprofilesdata                                                     1.5MB         1586399             1593344
c:\users\username\appdata\roaming\code\cachedextensions                                                       739.8KB        757539              757760
c:\users\username\appdata\roaming\code\service worker\scriptcache                                             737.2KB        754919              929792
c:\users\username\appdata\roaming\code\dawncache                                                              544.4KB        557424              561152
c:\users\username\appdata\roaming\code\gpucache                                                               544.4KB        557424              561152
c:\users\username\appdata\roaming\code\user\globalstorage\ms-azuretools.vscode-azurefunctions\~4\net6.0\cache 248.2KB        254163              266240
c:\users\username\appdata\roaming\code\user\globalstorage\ms-azuretools.vscode-azurefunctions\~3\net6.0\cache 141KB          144365              159744
c:\users\username\appdata\roaming\code\code cache                                                             144               144               49152
c:\users\username\appdata\roaming\code\cachedconfigurations                                                   72                 72               16384
c:\users\username\appdata\roaming\code\user\globalstorage\vscode-redhat-telemetry\cache                       0                   0                   0

MS Teams stores another 1.76 GiB, and Slack another 742 MiB (but at least that one has an excuse, it's not a Microsoft product).

From an old Microsoft Technet Managing Roaming User Data Deployment Guide:

Windows uses the Local and LocalLow folders for application data that does not roam with the user. Usually this data is either machine specific or too large to roam.

4 GiB of cache data is too much to sync at every login.

@MurzNN
Copy link

MurzNN commented Aug 28, 2023

I created a separate issue about cache data #191434 but it's closed as a duplicate of this, so duplicating here my list of directories with cache data on Linux systems, that should be moved to $XDG_CACHE_HOME:

  • .config/Code/Cache
  • .config/Code/CachedConfigurations
  • .config/Code/CachedData
  • .config/Code/CachedExtensionVSIXs
  • .config/Code/CachedExtensions
  • .config/Code/CachedProfilesData
  • .config/Code/Code Cache
  • .config/Code/DawnCache
  • .config/Code/GPUCache
  • .config/Code/Service Worker/CacheStorage
  • .config/Code/Service Worker/ScriptCache
  • .vscode-server/extensionsCache
  • .vscode-server/data/CachedExtensions
  • .vscode-server/data/CachedProfilesData
  • extensions cache data like .vscode-server/data/User/globalStorage/redhat.vscode-yaml/schemas_cache

@MurzNN
Copy link

MurzNN commented Aug 28, 2023

Also, want to point to the more general Electron bug about using configuration folders as cache folders: electron/electron#8124

@C0rn3j
Copy link

C0rn3j commented Feb 9, 2024

@Tyriar On Linux $XDG_CONFIG_HOME is already used for most/all of the mentioned directories, not $HOME/.config - which is what it defaults to.

i.e. ${XDG_CONFIG_HOME:-$HOME/.config}

Would be nice to update the OP with the current paths, easy to test via:

mkdir -p "${HOME}/testdir"; export XDG_CONFIG_HOME="${HOME}/testdir"; code

@blubberdiblub
Copy link

@C0rn3j Note that one of the points of this folder structure problems is that $XDG_CONFIG_HOME or $HOME/.config (or %APPDATA% on Windows) is not the correct place for some things, but they currently end up there anyway.

Some things should actually go into $XDG_CACHE_HOME (also $XDG_DATA_HOME and $XDG_STATE_HOME if I were concerned, but the cache separation is much more important) or $HOME/.cache (or %LOCALAPPDATA% on Windows), but they currently don't.

@mcnesium
Copy link

mcnesium commented Feb 9, 2024

Stuff like window.zoomLevel should not go into settings.json because it is state and not config. If set up with home-manager, VScode is not able to write to that file and thus throws errors everytime you use ctrl + or crtl -.

@minecraftchest1
Copy link

560 Upvotes. 30 or so separate linked issues. Perhaps this issue should be split up into several smaller tasks that can be worked on separately.

  • Separating out cache files (zero impact to end users. Symlinks can be used to work around the Electron bug.)
  • Defining a folder structure, deciding what goes where (This appears to already be mostly done, just needs to be all put in one place)
  • Working out a migration strategy for other files and folders. (Revisit VS Code folder structure for app data, settings, extensions #3884 (comment) would be a good place to start.)
  • Compiling a list of everything that needs to be changed. (I believe some work on this has been started, but got lost in all of the noise.)
  • Implementing new folder structure and migration.

Creating dedicated tickets for each of the items above would help reduce noise, make the tasks feel more manageable (increasing motivation), and help encourage community participation.

This is just my 2 cents.

@thepkc
Copy link

thepkc commented Sep 24, 2024

Any chance this could have someone working on it?

@Volatus
Copy link

Volatus commented Sep 25, 2024

I was hoping to take a stab at it but getting the local dev env working was too much of a hassle @thepkc

@casperlehmann
Copy link

casperlehmann commented Nov 9, 2024

As a Mac user, I would like to underline that the XDG convention is not just for Linux users -- we rely on it as well.

Since this is a big change, and we are likely not getting another chance at fixing it, I think it's important to get it right. Reading this discussion (and the current outline in the top post), I get the impression that you would like to clean .vscode out from everyone's home directories (thanks, appreciated), and you want to rely on the given platform standards for deciding on a solution.

From a Mac user perspective: I am convinced that you would find that most engineers reaching this thread are here because they want to be able to manage their setup on their own terms. We want to be able to source control our dotfiles, and we do that the same way that the Linux folk do it (e.g. using GNU Stow). So while Apple does have guidelines for where to store which pieces of data, that does not need to be the end all be all. It's just a recommendation, just like $HOME/.config is a recommendation for Linux.

Take this code, for example:

case 'darwin':
appDataPath = path.join(os.homedir(), 'Library', 'Application Support');
break;
case 'linux':
appDataPath = process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config');
break;

Please, do use Apple's recommended standard path as a default, but allow us to set the same freedom as you would Linux, like this:

case 'darwin':
-	appDataPath = path.join(os.homedir(), 'Library', 'Application Support');
+	appDataPath = process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), 'Library', 'Application Support');
	break;
case 'linux':
	appDataPath = process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config');
	break;

If there is proper separation between cache, data and config, I would not expect the Linux and Darwin setup to differ all that much, so if you got it working on Linux, synching the XDG functionality to Mac should just be a question of running a findAll: XDG) and copying it for the other platform.

@klmcwhirter
Copy link

klmcwhirter commented Nov 17, 2024

Please be aware that many of us on Linux and perhaps macOS are still waiting for this to be addressed.

I totally agree with the content from #3884 (comment).

This is not about $HOME/.config ... we are looking for $XDG_CONFIG_HOME to be utilized.

Many apps are now adherent to the XDG standard as published at XDG Base Directory Specification.

Note this is also a helpful reference: XDG Base Directory at wiki.archlinux.org.

And please DO clean up the code / Code / vscode naming mess as you can - please just pick one. This creates more confusion for less skilled engineers than you realize.

FYI - (for what it is worth) I prefer vscode. I am sure there are a lot of opinions out there. I only feel strongly about the need for consistency though.

Similarly, although probably not relevant here, I would prefer vs or vstudio over deveng for Visual Studio proper.

Thanks.

@jarodtaylor
Copy link

jarodtaylor commented Jan 15, 2025

It's probably the most used IDE, and you guys still haven't made it possible to allow at least developers to change the location of their settings/extensions/keybindings/etc.

This should be as simple as:

export VSCODE_SETTINGS_FILE="${XDG_CONFIG_HOME:-${HOME}/.config}/vscode/settings"
export VSCODE_EXTENSIONS_DIR="${XDG_CONFIG_HOME:-${HOME}/.config}/vscode/extensions"
...etc

or something to that effect.

I mean, I use neovim but for the occasional IDE need, I would use VSC, Zed, etc, so why not let people control where they configure things?

@lgarron
Copy link

lgarron commented Jan 16, 2025

This should be as simple as:

export VSCODE_SETTINGS_FILE="${XDG_CONFIG_HOME:-${HOME}/.config}/vscode/settings"
export VSCODE_EXTENSIONS_DIR="${XDG_CONFIG_HOME:-${HOME}/.config}/vscode/extensions"
...etc

or something to that effect.

Since this seems to get lost every once in a while: there is no way to set persistent environment variables for a user1 on macOS. The closest is to set up a deamon to run launchctl setenv as soon as possible after a user logs in. However, there is no reliable way to make sure this runs at login before applications launch (or re-launch, in the case of a restart).

In order to be effective for macOS users, the solution needs to work without environment variables.

One option would be to check the filesystem for XDG-compatible paths, as I outlined at: #162712

But I think many of us on macOS would also be sufficiently happy if VS Code just placed its files in appropriate folders under ~/Library.

And I think we'd be the most glad if the VS Code team would be willing to commit to any given solution. I think many of us would be eager to send a PR if we know it will move the issue forward instead of just leading to further discussion. This issue is on the first page of the most upvoted issues and is a way to make a lot of users happier with a relatively small code change.

Footnotes

  1. Or for an app every time it's run by a user, short of hacking the .app itself every time it updates.

@RokeJulianLockhart

This comment has been minimized.

@lgarron
Copy link

lgarron commented Jan 16, 2025

#3884 (comment)

@lgarron, apple.stackexchange.com/revisions/424695/1 cites stackoverflow.com/revisions/36161817/4, which appears to describe a native method of applying environment variables at boot time.

With all due respect, this is misinformation.

  1. It applies at login time, not at boot time.
  2. It is not guaranteed to run before apps launch.

(You might note that I already covered this in the comment you are replying to.)

I know this because I have a daemon configured exactly like this.

I just performed a reboot to double-check if maybe it was more reliable now. But no, the env vars set in this way were not available in apps that relaunched as part of the reboot login.

(I'd love to be proven wrong if I'm missing something. You can see my configuration here. But even if this does work, 1) Apple's official docs on this do not specify a way to ensure a daemon is started before any apps are launched1, 2) Apple has changed this kind of stuff without notice and may break it again at any time, and 3) compared to proper macOS settings, this is not beginner-friendly and very unsatisfying compared to normal dotfile management.)

Believe me, I'd love not to have to worry about these fussy details and just pick the first practical and safe thing that works. I'd even re-enable my code to set $VSCODE_EXTENSIONS if VS Code could receive the env var consistently when it starts (which would address part of the VS Code issue we're discussing).

But I'm still not aware of a way. 😔

Footnotes

  1. Although the man page (x-man-page://launchd.plist) does amusingly state that "This key (RunAtLoad) should be avoided".

@lgarron
Copy link

lgarron commented Jan 16, 2025

I think I was a bit unnecessarily salty in my last comment, but I guess there are some things that are not common knowledge. Here is an explicit demonstration of why environment variables are not sufficient for macOS users, at least using the widely cited daemon approach.

  1. Create a launch daemon and reboot as follows:
# Open VS Code (so it relaunches automatically when logging in after reboot, at least with default macOS settings)
open -a "Visual Studio Code"

mkdir -p ~/vscode-env-var-test
cat << EOF > ${HOME}/Library/LaunchAgents/vscode-env-var-test.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
    <key>Label</key>
    <string>com.example.vscode-env-var-test</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>date &gt; ${HOME}/vscode-env-var-test/date.txt &amp;&amp; launchctl setenv VSCODE_EXTENSIONS ${HOME}/vscode-env-var-test/extensions</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

# Reboot (with sudo prompt)
sudo reboot now
  1. Upon reboot, observe that:
  • ~/vscode-env-var-test/date.txt shows that the code runs significantly after login (about half a minute in my case, well after apps have visibly launched).
  • VS Code reopens using its default extensions folder.
  1. Reopen VS Code and observe that it now uses the specified $VSCODE_EXTENSIONS.

Note that this is a significantly worse user experience, because you have two extension folders and VS Code sometimes uses one and sometimes the other. I can imagine someone getting very confused why their extension installations sometimes don't persist, or that they're suddenly running extensions they thought they had uninstalled. Or that they're running a different version of an extension than they thought they had configured. Depending on the extensions, this can result in mangled code or a broken VS Code setup.

This demonstrates that a solution without environment variables is needed for macOS users.

P.S. Clean up the test code using:

rm -f ${HOME}/Library/LaunchAgents/vscode-env-var-test.plist
rm -rf ${HOME}/vscode-env-var-test/
launchctl unsetenv VSCODE_EXTENSIONS

# Close and reopen VS Code to restore the normal extensions folder
osascript -e 'tell application "Visual Studio Code" to quit'
open -a "Visual Studio Code"

@praetorxyn
Copy link

praetorxyn commented Jan 16, 2025

Whether I'm using Mac or Linux I habitually launch code from the terminal, so my environment variables are always loaded because the shell loads them :)

@marcusrbrown
Copy link

The workaround for the daemon's unpredictable startup timing is to kill (and relaunch) all apps used to launch other executables after all launchctl setenv commands. The relaunched processes, as will their child processes, will use the variables set by the daemon.

In my setup, I restart the following: Finder, Dock, Raycast, iTerm, etc. Any app launched by these will see the "global" variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debt Code quality issues feature-request Request for new features or functionality workbench-os-integration Native OS integration issues
Projects
None yet