How do I open a URL or file from Neovim using the system's default application?
Answer
vim.ui.open()
Explanation
vim.ui.open(path_or_url) (Neovim 0.10+) opens a file path or URL using the operating system's default handler — your browser for https:// links, your file manager for directories, or the registered app for any other file type. It replaces the old Vimscript pattern of call system('xdg-open ' . shellescape(url)) with a clean, cross-platform Lua API.
How it works
- On Linux: delegates to
xdg-open - On macOS: delegates to
open - On Windows: delegates to
start - Returns a
SystemObj(same asvim.system()), so you can call:wait()or attach a callback - Neovim 0.10+ wires
gx(open URL under cursor) tovim.ui.open()internally
Example
-- Open URL under cursor in default browser
vim.keymap.set('n', 'gx', function()
local target = vim.fn.expand('<cfile>')
vim.ui.open(target)
end, { desc = 'Open URL under cursor' })
-- Open the current file's directory in the system file manager
vim.keymap.set('n', '<leader>E', function()
vim.ui.open(vim.fn.expand('%:p:h'))
end, { desc = 'Open file manager here' })
-- Open a URL from Lua code and wait for the process to exit
vim.ui.open('https://neovim.io'):wait()
Tips
- You can override
vim.ui.openwith your own implementation for consistent behavior across plugins that call it - The function is a no-op if no handler is found for the given path or URL — check the returned
SystemObj.codefor errors - Pairs well with
vim.fn.expand('<cfile>')to extract the file/URL under the cursor, which handles~expansion andfile://prefixes