Neovim Syntax Highlighting and Formatting for Caddy

Posted on Sep 26, 2025

I’ve been working with Caddyfiles a lot recently and Neovim doesn’t handle syntax highlighting or formatting them out of the box. Fortunately, it’s very easy to get set up with the help of the nvim-treesitter/nvim-treesitter and stevearc/conform.nvim packages.

First, you’ll need to set up the filetype. I use a .caddy extension for external imports.

init.lua
    -- Filetypes
vim.filetype.add {
  extension = {
    caddy = 'caddy',
  },
  filename = {
    Caddyfile = 'caddy',
  },
}
  

Next add the Caddyfile parser to nvim-treesitter.

treesitter.lua
    return { -- Highlight, edit, and navigate code
  'nvim-treesitter/nvim-treesitter',
  build = ':TSUpdate',
  main = 'nvim-treesitter.configs', -- Sets main module to use for opts
  opts = {
    ensure_installed = {
      'php',
      'bash',
      'c',
      'diff',
      'html',
      'lua',
      'luadoc',
      'markdown',
      'markdown_inline',
      'query',
      'vim',
      'vimdoc',
      'caddy', -- added
     },
    auto_install = true,
    highlight = {
      enable = true,
      additional_vim_regex_highlighting = { 'ruby' },
    },
    indent = { enable = true, disable = { 'ruby' } },
  },
}
  

Finally, add a custom formatter for Caddyfiles to conform.nvim. This assumes that the caddy binary is available in your path. Adjust the command as needed for your system.

conform.lua
    return { -- Autoformat
  'stevearc/conform.nvim',
  event = { 'BufWritePre' },
  cmd = { 'ConformInfo' },
  keys = {
    {
      '<leader>cf',
      function()
        require('conform').format { async = true, lsp_format = 'fallback' }
      end,
      mode = 'n',
      desc = '[F]ormat buffer',
    },
  },
  opts = {
    notify_on_error = true,
    format_on_save = function(bufnr)
      local disable_filetypes = { c = true, cpp = true }
      if disable_filetypes[vim.bo[bufnr].filetype] then
        return nil
      else
        return {
          timeout_ms = 4000,
          lsp_format = 'fallback',
        }
      end
    end,
    formatters = {
      caddy = { -- added
        command = 'caddy',
        args = { 'fmt', '-' },
        stdin = true,
      },
    },
    formatters_by_ft = {
      lua = { 'stylua' },
      php = { 'pint', 'mago_format', stop_after_first = true },
      blade = { 'blade-formatter', stop_after_first = true },
      javascript = { 'biome', 'prettier', stop_after_first = true },
      json = { 'biome', 'prettier', stop_after_first = true },
      html = { 'prettier', stop_after_first = true },
      css = { 'prettier', stop_after_first = true },
      caddy = { 'caddy' }, --added
    },
  },
}
  

And the result…

A screenshot showing a Caddyfile in Neovim with syntax highlighting

References