{"id":15399,"library":"tiny-lr-fork","title":"Tiny LiveReload Fork","description":"tiny-lr-fork is an actively maintained fork of the original `tiny-lr` package, which had become unmaintained. It provides a lightweight, background-friendly LiveReload server implementation for development workflows. Unlike the original, this fork addresses lingering issues, incorporates community contributions, and includes security patches. Key differentiators include quieter operation (reduced `console.log` output), proper handling of WSS for `livereload.js` over HTTPS, and normalized Windows file paths. The server exposes a simple HTTP/WebSocket API that build tools (like Grunt, or custom scripts) can use to notify connected LiveReload clients (browser extensions or injected scripts) about file changes. It does not perform file watching itself, requiring external integration for detecting changes. The current stable version, as per the changelog, is 2.0.0, with a release cadence driven by bug fixes and necessary updates rather than a fixed schedule.","status":"active","version":"0.0.5","language":"javascript","source_language":"en","source_url":"git://github.com/mklabs/tiny-lr","tags":["javascript"],"install":[{"cmd":"npm install tiny-lr-fork","lang":"bash","label":"npm"},{"cmd":"yarn add tiny-lr-fork","lang":"bash","label":"yarn"},{"cmd":"pnpm add tiny-lr-fork","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Commonly used as a middleware host, though not a direct runtime dependency of the core server.","package":"connect","optional":true},{"reason":"Commonly used as a middleware host, though not a direct runtime dependency of the core server.","package":"express","optional":true},{"reason":"The client-side script that connects to the tiny-lr server. Implicitly relied upon for functionality.","package":"livereload-js","optional":false}],"imports":[{"note":"Primarily a CommonJS package. While Node.js supports ESM, its API is designed for `require()`.","wrong":"import tinylr from 'tiny-lr';","symbol":"tinylr","correct":"const tinylr = require('tiny-lr');"},{"note":"The `Server` constructor is exposed directly on the main module export. The main export can also be called as a function `tinylr()` to create a server instance directly.","wrong":"import { Server as LiveReloadServer } from 'tiny-lr';","symbol":"tinylr.Server","correct":"const LiveReloadServer = require('tiny-lr').Server;"},{"note":"Used to integrate tiny-lr as a Connect/Express middleware. It should be used after body parsing and query parsing middleware.","wrong":"import { middleware as lrMiddleware } from 'tiny-lr';","symbol":"tinylr.middleware","correct":"const lrMiddleware = require('tiny-lr').middleware;"}],"quickstart":{"code":"const tinylr = require('tiny-lr');\nconst path = require('path');\nconst express = require('express');\n\nconst PORT = 35729; // Standard LiveReload port for browser extensions\nconst app = express();\n\n// Initialize tiny-lr server\nconst lrserver = tinylr();\n\n// Listen for specific requests on the tiny-lr server (optional)\nlrserver.on('GET /custom-status', (req, res) => {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('tiny-lr server is running and custom route works!');\n});\n\n// Integrate tiny-lr middleware with Express\n// In modern Express, query parsing is built-in, but body-parser might still be needed.\napp.use(express.json()); // For POST requests with JSON body\napp.use(express.urlencoded({ extended: true })); // For URL-encoded bodies\napp.use(lrserver.middleware({ app: app })); // Bind tiny-lr routes to the Express app\n\n// Serve static files (e.g., your project's root)\napp.use(express.static(path.resolve('./')));\n\n// Start the Express app and tiny-lr server\napp.listen(PORT, function() {\n  console.log(`Express app and tiny-lr server listening on port ${PORT}`);\n  console.log('Use `curl http://localhost:35729/changed?files=index.html` to trigger reloads.');\n  console.log('Or `curl -X POST http://localhost:35729/changed -d \"{\\\"files\\\":[\\\"style.css\\\"]}\"`');\n});\n\n// Example of how to trigger a reload programmatically\n// setTimeout(() => {\n//   lrserver.changed({ body: { files: ['index.html'] } });\n//   console.log('Triggered a reload after 5 seconds.');\n// }, 5000);\n","lang":"javascript","description":"This quickstart demonstrates how to set up `tiny-lr-fork` as a standalone LiveReload server integrated with an Express application, listening on the default port 35729. It shows both starting the server and integrating its middleware for handling reload requests, along with an example of a custom route. It also includes `curl` commands to trigger reloads."},"warnings":[{"fix":"Upgrade client-side browser versions or ensure your development setup does not require LiveReload functionality for IE6-9.","message":"Version 2.0.0 of tiny-lr-fork, alongside its dependency `livereload-js`, has officially dropped support for Internet Explorer versions 6 through 9. Projects targeting these legacy browsers will experience issues.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure `app.use(express.json());` and `app.use(express.urlencoded({ extended: true }));` (or equivalent parsing middleware) are registered *before* `app.use(tinylr.middleware({ app: app }));`.","message":"When integrating `tiny-lr` as Connect/Express middleware, it requires query and body parsing middleware to be registered *prior* in the stack for POST requests to `/changed` to work correctly. For modern Express, `express.json()` and `express.urlencoded()` are needed.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For seamless browser extension integration, run `tiny-lr-fork` on port 35729. If a different port is necessary, manually edit the LiveReload browser extension's settings or use the manual script tag injection method with a `port` attribute in your HTML: `<script src=\"http://localhost:YOUR_PORT/livereload.js?snipver=1\"></script>`.","message":"The LiveReload browser extensions (Chrome, Firefox, Safari) by default connect to port `35729`. If you configure `tiny-lr-fork` to listen on a different port, the browser extension will not automatically connect. You will need to manually configure the extension or inject the `livereload.js` script with the correct port.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Integrate with a file watcher in your build process. Upon file change detection, send an HTTP request to `http://localhost:35729/changed?files=your_file.css` or a POST request with a JSON payload to the `/changed` endpoint.","message":"`tiny-lr-fork` is a server that *receives* reload notifications and broadcasts them. It does not include built-in file watching capabilities. You must use an external build tool (e.g., Gulp, Webpack, or a simple `fs.watch` script) to detect file changes and then notify `tiny-lr-fork`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always upgrade to the latest stable version of `tiny-lr-fork` to ensure all known security vulnerabilities in its dependencies are addressed. Current stable is >=2.0.0.","message":"Previous versions of `tiny-lr-fork` (and its original `tiny-lr` predecessor) had vulnerabilities in the `debug` and `qs` dependencies. While these have been patched in recent releases, it's crucial to stay updated.","severity":"deprecated","affected_versions":"<1.1.1"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Stop the conflicting process, or configure `tiny-lr-fork` to listen on a different port using the `-p` or `--port` command line option, or by passing a `port` option to `tinylr().listen(port, ...)`.","cause":"Another process, or a previous instance of your `tiny-lr-fork` server, is already listening on the specified port (default 35729).","error":"Error: listen EADDRINUSE: address already in use :::35729"},{"fix":"Ensure your `tiny-lr-fork` server is running. If using it as middleware, verify `app.use(lrserver.middleware({ app: app }));` is correctly placed in your Connect/Express application and the `app` object is the same as the one listening on the port.","cause":"The `tiny-lr-fork` server is either not running, or its middleware is not correctly mounted in your application stack, leading to the `/livereload` path not being handled.","error":"WebSocket connection to 'ws://localhost:35729/livereload' failed: Error during WebSocket handshake: Unexpected response code: 404"},{"fix":"For modern Express (4.x+), use `app.use(express.json());` and `app.use(express.urlencoded({ extended: true }));` to handle body and query parsing before the `tiny-lr-fork` middleware.","cause":"This typically occurs when `express.bodyParser()` or `express.query()` are referenced as middleware in older examples, but are either not imported or are deprecated in your version of Express.","error":"TypeError: app.use() requires a middleware function but got a undefined"}],"ecosystem":"npm"}