npm i vscode-use-package


Programmatic configuration for VS Code

by Bodil Stokke

0.1.4 (see all)TypeScript:Not Found
npm i vscode-use-package


Programmatic configuration, extension management and keybinding for VS Code, to go with the init-script extension.

This is heavily inspired by John Wiegley's use-package system for Emacs.


vscode-use-package provides the usePackage function, which takes care of installing and configuring extensions from your init.ts file. The advantage of this is that you can easily maintain (and, perhaps more importantly, keep in version control) a consistent VS Code configuration across multiple computers and OS installations.

The recommended way to install this is using npm in the folder where you keep your init.ts script:

$ cd ~/.config/Code/User # or equivalent
$ npm add vscode-use-package

In this way, you can simply import it in your init.ts file (or require it in your init.js file, if you prefer):

import { initUsePackage, usePackage } from "vscode-use-package";


usePackage takes a package name (<publisher>.<extension-name> as found in the "Installation" header on the Marketplace page) and an optional configuration object. It will check if the extension is already installed, install it for you if it's not, then go ahead and configure it according to your specifications.

The configuration object looks like this (and all the keys are optional):

export type UsePackageOptions = {
    local?: boolean;
    remote?: string | boolean;
    scope?: string;
    config?: Record<string, any>;
    globalConfig?: Record<string, any>;
    keymap?: Array<Keybinding>;
    init?: () => Thenable<void>;

local and remote

If you pass the option local: true, this extension will not install on remotes such as WSL or an SSH host. If you pass remote: true, it will only install if you're running on a remote. This is useful if you have a single init script for all your development environments, but you use extensions which aren't designed to run either locally or remotely.

Specifically, UI extensions have to be installed locally and cannot be installed at all by an init script running on a remote instance. You should therefore flag UI extensions local: true and make sure you run your init script locally before connecting to a remote host.

With the remote property, you can also specify a string which will be matched against vscode.env.remoteName, so that you can eg. use remote: "wsl" to restrict an extension to only install on WSL remotes. Check the VS Code API documentation for more info on vscode.env.remoteName.


The config property takes an object of configuration keys and values, and updates the VS Code configuration accordingly. The keys will be automatically namespaced to the package you're configuring: usePackage("my-package", {config: {enableFeature: true}}) will result in the configuration key my-package.enableFeature being set to true.

If the name of the configuration scope differs from the name of the package, as, unfortunately, often happens, you can use the scope property to override it.

As an example, here is how you'd install the GitLens package and configure it to stop showing you annotations for the current line:

usePackage("eamodio.gitlens", {
    config: {
        "currentLine.enabled": false,


If you need to set options outside the package scope, use the globalConfig property, and feed it fully namespaced keys, as you would in settings.json.

For instance, this is how you could install a new syntax theme and enable it automatically:

usePackage("jack-pallot.atom-dark-syntax", {
    globalConfig: { "workbench.colorTheme": "Atom Dark Syntax" },


The keymap property is used to define keybindings for the package. The commands, unlike the settings keys, are not automatically prefixed with the package scope. The format is (or is supposed to be) equivalent to keybindings.json.

The Keybinding type looks like this:

export type Keybinding = {
    key: string;
    command: string;
    when?: string;
    args?: Record<string, string>;

Here is how you use it:

usePackage("garaemon.vscode-emacs-tab", {
    scope: "emacs-tab",
    keymap: [
            key: "tab",
            command: "emacs-tab.reindentCurrentLine",
            when: "editorTextFocus",


The init property takes a function which will be called once the package is installed and everything else is configured, in case you need to do any configuration that isn't covered by the other properties.

usePackage("jack-pallot.atom-dark-syntax", {
    globalConfig: { "workbench.colorTheme": "Atom Dark Syntax" },
    init: () => alert("syntax theme installed!"), // please don't do this, though

configSet and keymapSet

In addition to usePackage, the vscode-use-package module exports the configSet(scope: string, options: Record<string, any>) function and the keymapSet(keymap: Array<Keybinding>) function. These are the function usePackage calls to set config options and keybindings, but you might want to use these to configure settings unrelated to extensions:

configSet("workbench", {
    "editor.showTabs": false,
    "editor.enablePreview": false,
    "activityBar.visible": true,

        key: "ctrl+x ctrl+c",
        command: "workbench.action.quit",

Note that you can also call configSet(options: Record<string, any>) without the scope argument to set top level options.


Please keep in mind that usePackage runs asynchronously, so that code invoked after usePackage calls is not guaranteed to (and almost certainly won't) run after the package is installed and configured.

However, usePackage calls are performed in sequence, in invocation order, so that packages can assume previous packages have been fully installed, and code in a usePackage's init hook is guaranteed to run after all previous usePackages have fully completed.

If you need to wait for the completion of a usePackage call, it returns a Promise<void> that you can await the resolution of. Because usePackage calls run in order, if you need to wait for everything to fully complete, you can just wait for your last usePackage to complete.


Copyright 2019 Bodil Stokke

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see

Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.



GitHub Stars



2yrs ago








2yrs ago
No alternatives found
No tutorials found
Add a tutorial