A Practical LazyVim Setup for Web Development

Build a focused LazyVim environment for TypeScript work with explicit language tooling, formatting, and reproducible configuration.

A code editor connected to modular web development tools

A useful Neovim setup is not the one with the most plugins. It is the one where editing, navigation, diagnostics, and formatting behave predictably.

For web development, I start with LazyVim and add language support deliberately.

Install the foundation

On macOS:

Terminal window
brew install neovim git fd ripgrep

Confirm Neovim starts before adding configuration:

Terminal window
nvim --version
nvim --clean

Then follow the current LazyVim installation guide. Keep your configuration in Git from the beginning. A broken experiment is much easier to undo when the previous state is a commit rather than a memory.

Enable only the language extras you need

My current configuration always loads JSON and Markdown support. A web profile adds TypeScript, Tailwind CSS, Docker, Prisma, ESLint, and Prettier extras:

if profile.is("web") then
vim.list_extend(spec, {
{ import = "lazyvim.plugins.extras.lang.typescript" },
{ import = "lazyvim.plugins.extras.lang.tailwind" },
{ import = "lazyvim.plugins.extras.lang.docker" },
{ import = "lazyvim.plugins.extras.lang.prisma" },
{ import = "lazyvim.plugins.extras.linting.eslint" },
{ import = "lazyvim.plugins.extras.formatting.prettier" },
})
end

This is more maintainable than installing every language server on every machine. It also keeps the source of each default visible: LazyVim owns the baseline; local plugin files contain only deliberate overrides.

Separate responsibilities

I keep the setup split by concern:

lua/
├── config/
│ ├── lazy.lua
│ ├── keymaps.lua
│ ├── options.lua
│ └── profile.lua
└── plugins/
├── coding.lua
├── conform.lua
├── lsp.lua
├── snacks.lua
└── treesitter.lua

Language servers provide diagnostics and code intelligence. Conform owns formatting. Snacks owns file search, grep, explorer, and terminal workflows. Blink provides completion. Clear ownership prevents two plugins from fighting over the same job.

Verify one layer at a time

After enabling a language:

  1. open a small real project;
  2. run :checkhealth;
  3. inspect attached servers with :LspInfo;
  4. confirm go-to-definition and diagnostics;
  5. format a deliberately messy file;
  6. restart once and repeat.

Do not debug completion, formatting, Treesitter, and LSP at the same time. Disable layers until the failure becomes obvious.

The current configuration is available in my dotfiles. Copy ideas, not the whole directory. Your formatter choices, language mix, and keymap habits are the parts that should stay personal.

Read more

All posts
  1. Neovim open beside terminal tools in the dotfiles desktop setup
  2. A calm editor window resolving commands into a clear workflow
  3. Glowing geometric rules transforming into structured JSON objects
  4. Lazy.nvim plugin manager using the shared Huế theme