diff --git a/modules/default.nix b/modules/default.nix
index 31451d6f8..f180423bd 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -28,6 +28,7 @@ let
     ./programs/ssh.nix
     ./programs/termite.nix
     ./programs/texlive.nix
+    ./programs/vim.nix
     ./programs/zsh.nix
     ./services/dunst.nix
     ./services/gnome-keyring.nix
diff --git a/modules/programs/vim.nix b/modules/programs/vim.nix
new file mode 100644
index 000000000..e019751a3
--- /dev/null
+++ b/modules/programs/vim.nix
@@ -0,0 +1,77 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.programs.vim;
+  defaultPlugins = [ "sensible" ];
+
+in
+
+{
+  options = {
+    programs.vim = {
+      enable = mkEnableOption "Vim";
+
+      lineNumbers = mkOption {
+        type = types.nullOr types.bool;
+        default = null;
+        description = "Whether to show line numbers.";
+      };
+
+      tabSize = mkOption {
+        type = types.nullOr types.int;
+        default = null; 
+        example = 4;
+        description = "Set tab size and shift width to a specified number of spaces.";
+      };
+
+      plugins = mkOption {
+        type = types.listOf types.str;
+        default = defaultPlugins;
+        example = [ "YankRing" ];
+        description = ''
+          List of vim plugins to install.
+          For supported plugins see: https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/vim-plugin-names
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        example = ''
+          set nocompatible
+          set nobackup
+        '';
+        description = "Custom .vimrc lines";
+      };
+    };
+  };
+
+  config = (
+    let
+      optionalBoolean = name: val: optionalString (val != null) (if val then "set ${name}" else "unset ${name}");
+      optionalInteger = name: val: optionalString (val != null) "set ${name}=${toString val}";
+      customRC = ''
+        ${optionalBoolean "number" cfg.lineNumbers}
+        ${optionalInteger "tabstop" cfg.tabSize}
+        ${optionalInteger "shiftwidth" cfg.tabSize}
+
+        ${cfg.extraConfig}
+      '';
+
+      vim = pkgs.vim_configurable.customize {
+        name = "vim";
+        vimrcConfig.customRC = customRC;
+        vimrcConfig.vam.knownPlugins = pkgs.vimPlugins;
+        vimrcConfig.vam.pluginDictionaries = [
+          { names = defaultPlugins ++ cfg.plugins; }
+        ];
+      };
+
+    in mkIf cfg.enable {
+      home.packages = [ vim ];
+    }
+  );
+}