Usage of OpenTofu Language Server
October 13, 2025 ยท View on GitHub
This guide assumes you have installed the server by following instructions
in the installation.md if the client doesn't download the server itself.
And make sure tofu-ls command is accessible.
Note
If you are unable to configure tofu-ls command to be directly accessible by the editor.
You can enter the absolute path of the tofu-ls binary instead.
The following filetypes are supported by the OpenTofu Language Server:
opentofu- standard*.tfand*.tofuconfig filesopentofu-vars- variable files (*.tfvars)
We also accept terraform and terraform-vars as language IDs, to support wider range of editors.
For consistent behavior we encourage users to remap them to corresponding opentofu IDs.
Note
Clients should be configured to follow the above language ID conventions
and do not send *.tf.json, *.tfvars.json nor Packer HCL config
nor any other HCL config files as the server is not equipped to handle these file types.
In most clients with a dedicated OpenTofu extension/plugin this is already the default configuration, so you should not need to worry about it.
Instructions for popular IDEs are below and pull requests for updates or addition of more IDEs are welcomed.
See also settings to understand how you may configure the settings.
Workspaces / Folders / Files
Most editors support opening folders. Such a root folder is commonly referred to as "workspace". Opening folders is always preferred over individual files as it allows the language server to index the whole folder and keep track of changes more easily. We do however support "single-file mode" which provides limited IntelliSense.
Indexing enables IntelliSense related to module blocks,
such as go-to-definition, completion of module.* references,
or workspace-wide symbol lookup.
The server will not index any folders or files above the workspace root initially opened in the editor.
Emacs
Eglot
;; if you have doom emacs:
(set-eglot-client! '(terraform-mode :language-id "opentofu") '("tofu-ls" "serve"))
;; or without it, after loading `eglot`:
(add-to-list 'eglot-server-programs '((terraform-mode :language-id "opentofu") . ("tofu-ls" "serve")))
IntelliJ IDE
We do not have officially supported way to use tofu-ls with IntelliJ IDEs. If you must use tofu-ls you can try to find different ways to add generic language servers.
We recommend using official Terraform and HCL plugin. It provides overlapping functionality with this language server and in some way has more features.
Vim / NeoVim
coc.nvim
- Install the coc.nvim plugin
- Add the following snippet to the
coc-setting.jsonfile (editable via:CocConfigin NeoVim)
{
"languageserver": {
"opentofu": {
"command": "tofu-ls",
"args": ["serve"],
"filetypes": ["terraform", "tf"],
"initializationOptions": {},
"settings": {}
}
}
}
Make sure to read through the example vim configuration of the plugin, especially key remapping, which is required for completion to work correctly:
" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()
vim-lsp
- Install the following plugins:
- Add the following to your
.vimrc:
if executable('tofu-ls')
au User lsp_setup call lsp#register_server({
\ 'name': 'tofu-ls',
\ 'cmd': {server_info->['tofu-ls', 'serve']},
\ 'whitelist': ['terraform'],
\ })
endif
YouCompleteMe
- Install the following plugins:
- Add the following to your
.vimrc:
" Remove this line if additional custom language servers are set elsewhere
let g:ycm_language_server = []
if executable('tofu-ls')
let g:ycm_language_server += [
\ {
\ 'name': 'opentofu',
\ 'cmdline': [ 'tofu-ls', 'serve' ],
\ 'filetypes': [ 'terraform' ],
\ 'project_root_files': [ '.terraform', .git' ]
\ },
\ ]
endif
Neovim v0.11.0+
We can natively configure LSP in Neovim (0.11.0+).
The following is the lua configuration for tofu-ls:
-- tofu-ls lsp setup
vim.lsp.config['tofu_ls'] = {
cmd = { 'tofu-ls', 'serve' },
-- Base filetypes
filetypes = { 'terraform', 'terraform-vars' },
root_markers = {'.terraform', '.git'},
}
vim.lsp.enable('tofu_ls')
If you want to enable auto-formatting on save, add the following configuration
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
-- Auto-format on save
if client:supports_method('textDocument/formatting') then
vim.api.nvim_create_autocmd('BufWritePre', {
group = vim.api.nvim_create_augroup('tofu-ls', {clear=false}),
buffer = args.buf,
callback = function()
vim.lsp.buf.format({ bufnr = args.buf, id = client.id, timeout_ms = 1000 })
end,
})
end
end,
})
In case you are using '.tofu' files, you also need to add the filetype during the initialization. At the time of writing this, Neovim doesn't support opentofu file extensions by default.
-- Add OpenTofu filetype
vim.filetype.add({
extension = {
tofu = 'opentofu'
},
})
Make sure to read through Neovim LSP documentation if you need more detailed settings.
VS Code
- Install OpenTofu VS Code Extension
- Latest compatible version of the language server is bundled with the extension
- See Configuration in case you need to tweak anything. Default settings should work for majority of users though.
Zed
-
Install the OpenTofu Extension or add the following lines to your zed settings
{ "auto_install_extensions": { "opentofu": true } } -
Latest compatible version of the language server will be installed with this extension, if the binary is not already installed.
-
For configuration options, see the corresponding GitHub repository of the extension you installed.
BBEdit (Might require update)
BBEdit 14 added support for the Language Server Protocol so you'll need to upgrade to version 14 to use; this won't work for older versions of BBEdit.
- Open Preferences > Languages
- In Language-specific settings section, add an entry for OpenTofu
- In the Server tab, Set Command to
tofu-lsand Arguments toserve - Once you've correctly installed
tofu-lsand configured BBEdit, the status indicator on this settings panel will flip to green - If you'd like to pass any settings to the server you can do so via the Arguments field.
Kate
KDE Kate editor supports LSP and is user configurable.
- Open Kate configuration (
Settings->Configure Kateor Kate ->Preferenceson macOS) - Select LSP Client in the left pane
- Select User Server Settings tab
- Paste the following JSON and Save:
{
"servers": {
"opentofu": {
"command": ["/path/to/tofu-ls", "serve"],
"url": "https://github.com/opentofu/tofu-ls",
"highlightingModeRegex": "^(OpenTofu|OpenTofu-Vars|Terraform)$",
"rootIndicationFileNames": [".terraform", ".git"]
}
}
}
- Restart of the editor should not be necessary.
At the time of writing this guide, Kate along with most other editors do not have a separate language mode for OpenTofu.
Hence, this configuration will work on .tf and .tfvars files, in case you are using .tofu files, you will need to add Sources/OpenTofu as a new filetype with all appropriate extensions.
New filetypes can be configured from Settings -> Configure Kate > Open/Save > Modes & Filetypes.
Helix Editor
Add the following config to your defined languages.toml:
[language-server.tofu-ls]
command = "tofu-ls"
args = ["serve"]
[[language]]
name = "hcl"
language-id = "opentofu"
scope = "source.hcl"
file-types = ["tf", "tofu", "tfvars"]
auto-format = true
comment-token = "#"
block-comment-tokens = { start = "/*", end = "*/" }
indent = { tab-width = 2, unit = " " }
language-servers = [ "tofu-ls" ]
Then, you need to rebuild your grammars with the following two commands:
- hx -g fetch
- hx -g build
Check the health of the language with:
- hx --health hcl
Other text editors
Warning
Be careful when installing on extensions outside the OpenTofu organization, always read the source code to make sure what you're installing is safe.
There are two ways of finding extensions implementing tofu-ls for other text editors:
- There's a topic on Github called
tofu-ls. You can find it at here. The expectation is if you create an extension, you're going to add a topic on your project to be easily discoverable by other people on Github. - There's a curated list at https://awesome-opentofu.com/#helpers.