Skip to content

dominicnunez/vscode-nix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vscode-nix

A Nix flake that packages VS Code (Microsoft's official build) directly from binaries, with automated daily updates, Garnix binary caching, and declarative configuration for extensions, settings, and keybindings.

Features

  • Official Microsoft VS Code binaries (not VSCodium)
  • Supports Linux x64, Linux aarch64, macOS x64, and macOS aarch64
  • Automated daily updates via GitHub Actions
  • Pre-built binaries via Garnix for instant installation
  • Declarative extensions management
  • Settings and keybindings configuration via Nix
  • Smart Home Manager integration detection

Quick Start

# Run VS Code directly (no installation needed)
nix run github:dominicnunez/vscode-nix

# Or try it in a temporary shell
nix shell github:dominicnunez/vscode-nix -c code

Binary Cache

This flake uses Garnix for CI and binary caching. The nixConfig in flake.nix automatically configures the cache, so pre-built binaries are fetched without any manual setup.

If prompted to allow configuration from the flake, answer yes or add accept-flake-config = true to your Nix configuration.

Installation

As a Flake Input

Add to your flake.nix:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    vscode-nix.url = "github:dominicnunez/vscode-nix";
  };

  outputs = { self, nixpkgs, vscode-nix, ... }: {
    # NixOS system configuration
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ({ pkgs, ... }: {
          environment.systemPackages = [
            vscode-nix.packages.${pkgs.system}.default
          ];
        })
      ];
    };
  };
}

With Home Manager (Flake)

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    home-manager.url = "github:nix-community/home-manager";
    vscode-nix.url = "github:dominicnunez/vscode-nix";
  };

  outputs = { self, nixpkgs, home-manager, vscode-nix, ... }: {
    homeConfigurations."user@host" = home-manager.lib.homeManagerConfiguration {
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
      modules = [
        ({ pkgs, ... }: {
          home.packages = [
            vscode-nix.packages.${pkgs.system}.default
          ];
        })
      ];
    };
  };
}

Using the Overlay

{
  inputs.vscode-nix.url = "github:dominicnunez/vscode-nix";

  outputs = { self, nixpkgs, vscode-nix }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        {
          nixpkgs.overlays = [ vscode-nix.overlays.default ];
          environment.systemPackages = [ pkgs.vscode-nix ];
        }
      ];
    };
  };
}

Extensions Configuration

Using vscodeWithExtensions

The lib.vscodeWithExtensions function creates a VS Code derivation with extensions pre-configured. The second argument accepts a settings attrset, or an attrset with settings and keybindings when you want both:

{
  inputs.vscode-nix.url = "github:dominicnunez/vscode-nix";

  outputs = { self, nixpkgs, vscode-nix }: {
    packages.x86_64-linux.my-vscode = vscode-nix.lib.x86_64-linux.vscodeWithExtensions
      # Extensions list
      [
        "ms-python.python"
        "esbenp.prettier-vscode"
        "dbaeumer.vscode-eslint"
        "ms-vscode.cpptools@1.20.0"  # Pin specific version
      ]
      # Settings and keybindings (optional)
      {
        settings = null;
        keybindings = null;
      };
  };
}

Direct Package Configuration

You can also configure extensions directly when calling the package:

vscode-nix.packages.${system}.default.override {
  extensions = [
    "ms-python.python"
    "esbenp.prettier-vscode@10.0.0"  # Pinned version
  ];
}

Extensions are:

  • Installed on first run via VS Code's --install-extension command
  • Stored in ~/.local/share/vscode-nix/extensions (persists across updates)
  • Only reinstalled when the extension list changes

Settings Configuration

Provide VS Code settings as a Nix attribute set:

{
  packages.x86_64-linux.my-vscode = vscode-nix.lib.x86_64-linux.vscodeWithExtensions
    [ "ms-python.python" ]
    # Settings
    {
      "editor.fontSize" = 14;
      "editor.tabSize" = 2;
      "editor.formatOnSave" = true;
      "workbench.colorTheme" = "One Dark Pro";
      "files.autoSave" = "afterDelay";
      "python.languageServer" = "Pylance";
    };
}

Or using override:

vscode-nix.packages.${system}.default.override {
  userSettings = {
    "editor.fontSize" = 14;
    "editor.minimap.enabled" = false;
  };
}

Settings behavior:

  • Nix settings are used as defaults on first run
  • User modifications in VS Code are preserved and take precedence
  • If Nix settings change, they are merged with user settings (user wins on conflicts)
  • Settings stored in ~/.local/share/vscode-nix/user-data/User/settings.json

Keybindings Configuration

Provide custom keybindings as a list of attribute sets:

{
  packages.x86_64-linux.my-vscode = vscode-nix.lib.x86_64-linux.vscodeWithExtensions
    [ "ms-python.python" ]
    {
      settings = { "editor.fontSize" = 14; };
      # Keybindings
      keybindings = [
        { key = "ctrl+k ctrl+t"; command = "workbench.action.terminal.focus"; }
        { key = "ctrl+k ctrl+e"; command = "workbench.action.focusActiveEditorGroup"; }
        { key = "ctrl+shift+d"; command = "editor.action.duplicateSelection"; }
        {
          key = "ctrl+shift+/";
          command = "editor.action.blockComment";
          when = "editorTextFocus";
        }
      ];
    };
}

Or using override:

vscode-nix.packages.${system}.default.override {
  userKeybindings = [
    { key = "ctrl+k ctrl+t"; command = "workbench.action.terminal.focus"; }
  ];
}

Keybindings behavior:

  • Nix keybindings are added as defaults on first run
  • User modifications in VS Code are preserved
  • If Nix keybindings change, they are merged (user keybindings take precedence)
  • Duplicate keybindings are deduped by key, keeping the user entry
  • Keybindings stored in ~/.local/share/vscode-nix/user-data/User/keybindings.json

Full Configuration Example

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    vscode-nix.url = "github:dominicnunez/vscode-nix";
  };

  outputs = { self, nixpkgs, vscode-nix }: {
    packages.x86_64-linux.my-dev-environment =
      vscode-nix.lib.x86_64-linux.vscodeWithExtensions
        # Extensions
        [
          # Python development
          "ms-python.python"
          "ms-python.vscode-pylance"
 
          # JavaScript/TypeScript
          "esbenp.prettier-vscode"
          "dbaeumer.vscode-eslint"
 
          # Git
          "eamodio.gitlens"
 
          # Nix
          "jnoortheen.nix-ide"
 
          # Theme
          "zhuangtongfa.material-theme"
        ]
        {
          # Settings
          settings = {
            # Editor
            "editor.fontSize" = 13;
            "editor.fontFamily" = "'JetBrains Mono', 'Fira Code', monospace";
            "editor.fontLigatures" = true;
            "editor.tabSize" = 2;
            "editor.formatOnSave" = true;
            "editor.minimap.enabled" = false;
 
            # Files
            "files.autoSave" = "afterDelay";
            "files.trimTrailingWhitespace" = true;
 
            # Theme
            "workbench.colorTheme" = "One Dark Pro";
            "workbench.iconTheme" = "material-icon-theme";
 
            # Terminal
            "terminal.integrated.fontSize" = 12;
 
            # Python
            "python.languageServer" = "Pylance";
 
            # Nix
            "nix.enableLanguageServer" = true;
          };
          # Keybindings
          keybindings = [
            { key = "ctrl+k ctrl+t"; command = "workbench.action.terminal.focus"; }
            { key = "ctrl+k ctrl+e"; command = "workbench.action.focusActiveEditorGroup"; }
          ];
        };
  };
}

Home Manager Integration

This package includes smart Home Manager detection. When running VS Code:

If Home Manager is detected:

  • Skips creating ~/.local/bin/code symlink
  • Cleans up symlinks that were created by this package
  • Respects your declarative Home Manager configuration

If Home Manager is NOT detected:

  • Creates ~/.local/bin/code symlink for convenience
  • Allows running code from anywhere if ~/.local/bin is in your PATH

Automatic cleanup: If you previously installed vscode-nix standalone (creating a ~/.local/bin/code symlink) and later enable Home Manager, the package will automatically remove the symlink on first run to prevent PATH conflicts.

Detection Indicators

Home Manager is detected if any of these conditions are true:

  • HM_SESSION_VARS environment variable is set
  • ~/.config/home-manager directory exists
  • /etc/profiles/per-user/$USER directory exists

Enabling Verbose Messages

To enable informational messages from the wrapper:

export VSCODE_NIX_VERBOSE=1

Or add to your shell profile:

# ~/.bashrc or ~/.zshrc
export VSCODE_NIX_VERBOSE=1

Environment Variables

Variable Description Default
VSCODE_NIX_VERBOSE Set to 1 to enable wrapper messages unset
XDG_DATA_HOME Base directory for VS Code data ~/.local/share
XDG_CONFIG_HOME Base directory for VS Code config ~/.config

Data Directories

When using extensions, settings, or keybindings configuration:

Path Purpose
~/.local/share/vscode-nix/extensions Installed extensions
~/.local/share/vscode-nix/user-data User settings, keybindings, state

Contributing

How Updates Work

  1. Daily Check: GitHub Actions runs update.sh daily at 00:00 UTC
  2. Version Detection: Script queries GitHub API for latest VS Code release
  3. Hash Fetching: If newer version found, fetches SHA256 hashes for all platforms
  4. Validation: Runs nix flake check to verify package builds correctly
  5. Push: Pushes update directly to main

Manual Update

To manually trigger an update check:

  1. Go to Actions tab in GitHub
  2. Select "Update VS Code" workflow
  3. Click "Run workflow"

Local Development

# Enter development shell
nix develop

# Check for updates (dry run)
./update.sh

# Check and apply update
./update.sh --update

# Build the package
nix build

# Run the built package
nix run

# Run flake checks
nix flake check

Repository Structure

.
├── flake.nix           # Flake definition with outputs
├── flake.lock          # Locked dependencies
├── package.nix         # VS Code package derivation
├── version.json        # Current version and platform hashes
├── update.sh           # Update detection and hash fetching script
├── README.md           # This file
├── garnix.yaml         # Garnix CI configuration
└── .github/workflows/
    ├── update.yml      # Daily update workflow
    └── ci.yml          # Garnix build validation

License

VS Code is proprietary software from Microsoft. This flake packages the official binaries. See VS Code License for terms.

The Nix packaging code in this repository is MIT licensed.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •