diff --git a/book/src/languages.md b/book/src/languages.md
index 133e6447..e45ef910 100644
--- a/book/src/languages.md
+++ b/book/src/languages.md
@@ -39,7 +39,7 @@ injection-regex = "^mylang$"
 file-types = ["mylang", "myl"]
 comment-token = "#"
 indent = { tab-width = 2, unit = "  " }
-language-server = { command = "mylang-lsp", args = ["--stdio"] }
+language-server = { command = "mylang-lsp", args = ["--stdio"], environment = { "ENV1" = "value1", "ENV2" = "value2" } }
 formatter = { command = "mylang-formatter" , args = ["--stdin"] }
 ```
 
@@ -99,6 +99,7 @@ The `language-server` field takes the following keys:
 | `args`        | A list of arguments to pass to the language server binary             |
 | `timeout`     | The maximum time a request to the language server may take, in seconds. Defaults to `20` |
 | `language-id` | The language name to pass to the language server. Some language servers support multiple languages and use this field to determine which one is being served in a buffer |
+| `environment` | Any environment variables that will be used when starting the language server `{ "KEY1" = "Value1", "KEY2" = "Value2" }` |
 
 The top-level `config` field is used to configure the LSP initialization options. A `format`
 sub-table within `config` can be used to pass extra formatting options to
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 8dc34a3e..41ab23e1 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -207,6 +207,8 @@ pub struct LanguageServerConfiguration {
     #[serde(default)]
     #[serde(skip_serializing_if = "Vec::is_empty")]
     pub args: Vec<String>,
+    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
+    pub environment: HashMap<String, String>,
     #[serde(default = "default_timeout")]
     pub timeout: u64,
     pub language_id: Option<String>,
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs
index 90fd2f21..dd2581c6 100644
--- a/helix-lsp/src/client.rs
+++ b/helix-lsp/src/client.rs
@@ -42,10 +42,12 @@ pub struct Client {
 
 impl Client {
     #[allow(clippy::type_complexity)]
+    #[allow(clippy::too_many_arguments)]
     pub fn start(
         cmd: &str,
         args: &[String],
         config: Option<Value>,
+        server_environment: HashMap<String, String>,
         root_markers: &[String],
         id: usize,
         req_timeout: u64,
@@ -55,6 +57,7 @@ impl Client {
         let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
 
         let process = Command::new(cmd)
+            .envs(server_environment)
             .args(args)
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs
index f714395f..8418896c 100644
--- a/helix-lsp/src/lib.rs
+++ b/helix-lsp/src/lib.rs
@@ -550,6 +550,7 @@ fn start_client(
         &ls_config.command,
         &ls_config.args,
         config.config.clone(),
+        ls_config.environment.clone(),
         &config.roots,
         id,
         ls_config.timeout,