feat: replace npm live-server with pure-Lua HTTP server (#29)

## Problem

The plugin requires users to install Node.js and the `live-server` npm
package globally. This is a heavyweight external dependency for what
amounts to a simple local dev-server workflow, and it creates friction
for users who don't otherwise need Node.js.

## Solution

Replace the npm shell-out with a pure-Lua HTTP server built on `vim.uv`
(libuv bindings), eliminating all external dependencies. The new server
supports static file serving, SSE-based live reload, CSS hot-swap
without full page reload, directory listings, and recursive file
watching with configurable debounce.

Minimum Neovim version is bumped to 0.10 for `vim.uv` and `vim.ui.open`.
The old `args`-based config is automatically migrated with a deprecation
warning.

Closes #28.
This commit is contained in:
Barrett Ruth 2026-03-02 23:16:35 -05:00 committed by GitHub
parent baeb211719
commit f42f958c24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 1097 additions and 298 deletions

View file

@ -7,13 +7,13 @@ Homepage: <https://github.com/barrettruth/live-server.nvim>
INTRODUCTION *live-server.nvim*
live-server.nvim automatically reloads HTML, CSS, and JavaScript files in the
browser via a local development server.
browser via a local development server. No external dependencies required —
the server runs entirely in Lua using Neovim's built-in libuv bindings.
===============================================================================
REQUIREMENTS *live-server-requirements*
- Neovim >= 0.9.0
- live-server npm package (`npm install -g live-server`)
- Neovim >= 0.10
===============================================================================
CONFIGURATION *live-server-config*
@ -22,15 +22,23 @@ CONFIGURATION *live-server-config*
Configure via `vim.g.live_server` before the plugin loads: >lua
vim.g.live_server = {
args = { '--port=8080', '--no-browser' },
port = 8080,
browser = false,
}
<
*live_server.Config*
Fields: ~
{args} (`string[]`) Arguments passed to live-server via |vim.fn.jobstart()|.
Run `live-server --help` to see available options.
Default: `{ '--port=5555' }`
{port} (`integer?`) Port for the HTTP server. Default: `5500`
{browser} (`boolean?`) Auto-open browser on start. Default: `true`
{debounce} (`integer?`) Debounce interval in ms for file changes.
Default: `120`
{ignore} (`string[]?`) Lua patterns for file paths to ignore when
watching for changes. Default: `{}`
{css_inject} (`boolean?`) Hot-swap CSS without full page reload.
Default: `true`
{debug} (`boolean?`) Log each step of the hot-reload chain via
|vim.notify()| at DEBUG level. Default: `false`
===============================================================================
COMMANDS *live-server-commands*
@ -113,8 +121,32 @@ Lua keybinding to toggle server: >lua
Configuration with custom port and no auto-open: >lua
vim.g.live_server = {
args = { '--port=3000', '--no-browser' },
port = 3000,
browser = false,
}
<
Ignore node_modules and dotfiles: >lua
vim.g.live_server = {
ignore = { 'node_modules', '^%.' },
}
<
===============================================================================
KNOWN LIMITATIONS *live-server-limitations*
No Recursive File Watching on Linux ~
*live-server-linux-recursive*
libuv's `uv_fs_event` only supports recursive directory watching on macOS
(FSEvents) and Windows (ReadDirectoryChangesW). On Linux, the `recursive`
flag is silently accepted but ignored because inotify does not support it
natively. Only files directly in the served root directory trigger
hot-reload; files in subdirectories (e.g. `css/style.css`) will not be
detected.
See https://github.com/libuv/libuv/issues/1778
Enable `debug` in |live-server-config| to verify whether `fs_event`
callbacks fire for a given file change.
-------------------------------------------------------------------------------
vim:tw=78:ft=help:norl: