diff --git a/.gitmodules b/.gitmodules
index f4d6456c..a90766d4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -82,3 +82,7 @@
 	path = helix-syntax/languages/tree-sitter-toml
 	url = https://github.com/ikatyang/tree-sitter-toml
 	shallow = true
+[submodule "helix-syntax/languages/tree-sitter-elixir"]
+	path = helix-syntax/languages/tree-sitter-elixir
+	url = https://github.com/IceDragon200/tree-sitter-elixir
+	shallow = true
diff --git a/helix-syntax/languages/tree-sitter-elixir b/helix-syntax/languages/tree-sitter-elixir
new file mode 160000
index 00000000..295e62a4
--- /dev/null
+++ b/helix-syntax/languages/tree-sitter-elixir
@@ -0,0 +1 @@
+Subproject commit 295e62a43b92cea909cfabe57e8818d177f4857b
diff --git a/helix-syntax/src/lib.rs b/helix-syntax/src/lib.rs
index 79c1c1f5..bb0b2ec6 100644
--- a/helix-syntax/src/lib.rs
+++ b/helix-syntax/src/lib.rs
@@ -72,6 +72,7 @@ mk_langs!(
     (CSharp, tree_sitter_c_sharp),
     (Cpp, tree_sitter_cpp),
     (Css, tree_sitter_css),
+    (Elixir, tree_sitter_elixir),
     (Go, tree_sitter_go),
     // (Haskell, tree_sitter_haskell),
     (Html, tree_sitter_html),
diff --git a/languages.toml b/languages.toml
index 87f03d06..6b80763f 100644
--- a/languages.toml
+++ b/languages.toml
@@ -17,6 +17,15 @@ roots = []
 
 indent = { tab-width = 2, unit = "  " }
 
+[[language]]
+name = "elixir"
+scope = "source.elixir"
+injection-regex = "elixir"
+file-types = ["ex", "exs"]
+roots = []
+
+indent = { tab-width = 2, unit = "  " }
+
 [[language]]
 name = "json"
 scope = "source.json"
diff --git a/runtime/queries/elixir/highlights.scm b/runtime/queries/elixir/highlights.scm
new file mode 100644
index 00000000..b9ec0210
--- /dev/null
+++ b/runtime/queries/elixir/highlights.scm
@@ -0,0 +1,146 @@
+["when" "and" "or" "not in" "not" "in" "fn" "do" "end" "catch" "rescue" "after" "else"] @keyword
+
+[(true) (false) (nil)] @constant.builtin
+
+(keyword
+ [(keyword_literal)
+  ":"] @tag)
+
+(keyword
+ (keyword_string
+  [(string_start)
+   (string_content)
+   (string_end)] @tag))
+
+[(atom_literal)
+ (atom_start)
+ (atom_content)
+ (atom_end)] @tag
+
+(comment) @comment
+
+(escape_sequence) @escape
+
+(call function: (function_identifier) @keyword
+      (#match? @keyword "^(defmodule|defexception|defp|def|with|case|cond|raise|import|require|use|defmacrop|defmacro|defguardp|defguard|defdelegate|defstruct|alias|defimpl|defprotocol|defoverridable|receive|if|for|try|throw|unless|reraise|super|quote|unquote|unquote_splicing)$"))
+
+(call function: (function_identifier) @keyword
+      [(call
+        function: (function_identifier) @function
+        (arguments
+         [(identifier) @variable.parameter
+          (_ (identifier) @variable.parameter)
+          (_ (_ (identifier) @variable.parameter))
+          (_ (_ (_ (identifier) @variable.parameter)))
+          (_ (_ (_ (_ (identifier) @variable.parameter))))
+          (_ (_ (_ (_ (_ (identifier) @variable.parameter)))))]))
+       (binary_op
+        left:
+        (call
+         function: (function_identifier) @function
+         (arguments
+          [(identifier) @variable.parameter
+           (_ (identifier) @variable.parameter)
+           (_ (_ (identifier) @variable.parameter))
+           (_ (_ (_ (identifier) @variable.parameter)))
+           (_ (_ (_ (_ (identifier) @variable.parameter))))
+           (_ (_ (_ (_ (_ (identifier) @variable.parameter)))))]))
+        operator: "when")
+       (binary_op
+        left: (identifier) @variable.parameter
+        operator: _ @function
+        right: (identifier) @variable.parameter)]
+      (#match? @keyword "^(defp|def|defmacrop|defmacro|defguardp|defguard|defdelegate)$")
+      (#match? @variable.parameter "^[^_]"))
+
+(call (function_identifier) @keyword
+      [(call
+        function: (function_identifier) @function)
+       (identifier) @function
+       (binary_op
+        left:
+        [(call
+          function: (function_identifier) @function)
+         (identifier) @function]
+        operator: "when")]
+      (#match? @keyword "^(defp|def|defmacrop|defmacro|defguardp|defguard|defdelegate)$"))
+
+(anonymous_function
+ (stab_expression
+  left: (bare_arguments
+         [(identifier) @variable.parameter
+          (_ (identifier) @variable.parameter)
+          (_ (_ (identifier) @variable.parameter))
+          (_ (_ (_ (identifier) @variable.parameter)))
+          (_ (_ (_ (_ (identifier) @variable.parameter))))
+          (_ (_ (_ (_ (_ (identifier) @variable.parameter)))))]))
+ (#match? @variable.parameter "^[^_]"))
+
+(unary_op
+ operator: "@"
+ (call (identifier) @attribute
+       (heredoc
+        [(heredoc_start)
+         (heredoc_content)
+         (heredoc_end)] @doc))
+ (#match? @attribute "^(doc|moduledoc)$"))
+
+(module) @type
+
+(unary_op
+ operator: "@" @attribute
+ [(call
+   function: (function_identifier) @attribute)
+  (identifier) @attribute])
+
+(unary_op
+ operator: _ @operator)
+
+(binary_op
+ operator: _ @operator)
+
+(heredoc
+ [(heredoc_start)
+  (heredoc_content)
+  (heredoc_end)] @string)
+
+(string
+ [(string_start)
+  (string_content)
+  (string_end)] @string)
+
+(sigil_start) @string.special
+(sigil_content) @string
+(sigil_end) @string.special
+
+(interpolation
+ "#{" @punctuation.special
+ "}" @punctuation.special)
+
+[
+ ","
+ "->"
+ "."
+] @punctuation.delimiter
+
+[
+  "("
+  ")"
+  "["
+  "]"
+  "{"
+  "}"
+  "<<"
+  ">>"
+] @punctuation.bracket
+
+[(identifier) @function.special
+ (#match? @function.special "^__.+__$")]
+
+[(remote_identifier) @function.special
+ (#match? @function.special "^__.+__$")]
+
+[(identifier) @comment
+ (#match? @comment "^_")]
+
+(ERROR) @warning