{"id":12144,"library":"tiny-lr","title":"Tiny LiveReload Server","description":"tiny-lr is a minimalist LiveReload server implementation designed for integration into build workflows. It provides an HTTP server and Express middleware with a simple REST API to broadcast file change notifications to connected LiveReload clients. Unlike comprehensive live-reloading solutions, tiny-lr does not include file watching capabilities itself; users must integrate it with an external file watcher (e.g., from a build tool like Gulp or Grunt). The current stable version is 2.0.0, which marked a return to active development after a period of dormancy, focusing on dependency updates and modern browser compatibility. Its primary differentiators are its focused scope (only serving reload notifications), ease of integration into existing build chains, and low overhead, making it suitable for projects that prefer to manage file watching separately.","status":"active","version":"2.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/mklabs/tiny-lr","tags":["javascript"],"install":[{"cmd":"npm install tiny-lr","lang":"bash","label":"npm"},{"cmd":"yarn add tiny-lr","lang":"bash","label":"yarn"},{"cmd":"pnpm add tiny-lr","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"tiny-lr primarily uses CommonJS `require` syntax. As of v2.0.0, there is no official ESM support. The default export is a factory function that returns a server instance.","wrong":"import tinylr from 'tiny-lr';","symbol":"tinylr","correct":"const tinylr = require('tiny-lr');"},{"note":"The `Server` class can be accessed directly for more explicit instantiation, though the default `tinylr()` factory is more common. Still CommonJS only.","wrong":"import { Server as LiveReloadServer } from 'tiny-lr';","symbol":"tinylr.Server","correct":"const LiveReloadServer = require('tiny-lr').Server;"},{"note":"The Express/Connect middleware is a named export available on the main `tiny-lr` module. It requires `body-parser` to be used earlier in the middleware stack for handling POST requests.","wrong":"import { middleware as livereloadMiddleware } from 'tiny-lr';","symbol":"tinylr.middleware","correct":"const livereloadMiddleware = require('tiny-lr').middleware;"}],"quickstart":{"code":"const tinylr = require('tiny-lr');\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst path = require('path');\n\nconst port = process.env.LR_PORT || 35729; // Standard LiveReload port\nconst app = express();\n\n// Start the LiveReload server independently\nconst lrServer = tinylr();\nlrServer.listen(port, function() {\n  console.log(`LiveReload server listening on port ${port} (for browser extensions).`);\n});\n\n// Or integrate as Express middleware\napp.use(bodyParser.json());\napp.use(bodyParser.urlencoded({ extended: true }));\napp.use(tinylr.middleware({ app: app }));\n\napp.use(express.static(path.resolve('./public'))); // Serve static files\n\napp.get('/', (req, res) => {\n  res.send('<h1>Hello from tiny-lr!</h1><p>Check the browser console or network tab for livereload.js.</p>');\n});\n\n// Example of triggering a reload via HTTP API\n// This would typically be called by a build tool when files change.\n// curl http://localhost:35729/changed?files=index.html,style.css\n// curl -X POST http://localhost:35729/changed -d '{ \"files\": [\"script.js\"] }'\n\napp.listen(8000, () => {\n  console.log('Express server listening on port 8000.');\n  console.log('Open http://localhost:8000 in your browser and ensure LiveReload extension is active or script tag is added.');\n  console.log('To trigger a reload, send a POST request to http://localhost:35729/changed with a JSON body: { \"files\": [\"index.html\"] }');\n});\n\n// To manually trigger a reload (e.g., from your file watcher)\nfunction notifyChange(files) {\n  lrServer.changed({ body: { files: files } });\n  console.log('Notified LiveReload clients about:', files);\n}\n\n// Simulate a file change after 5 seconds\nsetTimeout(() => {\n  notifyChange(['index.html', 'style.css']);\n}, 5000);\n","lang":"javascript","description":"This quickstart demonstrates setting up a tiny-lr server on its standard port and integrating its middleware with an Express application. It also shows how to programmatically trigger a file change notification to connected LiveReload clients."},"warnings":[{"fix":"Upgrade browser target to modern browsers (IE10+ or equivalent) or downgrade tiny-lr to a 1.x version if IE 6-9 support is critical, understanding that older versions may have known vulnerabilities.","message":"Version 2.0.0 of tiny-lr includes a breaking change where the underlying `livereload-js` client library dropped support for Internet Explorer versions 6-9. Projects requiring compatibility with these legacy browsers should use an older version of tiny-lr or find an alternative.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Always configure the tiny-lr server to listen on port `35729` (e.g., `lrServer.listen(35729)`).","message":"For browser extensions (e.g., Chrome, Firefox LiveReload extensions) to function correctly, tiny-lr *must* listen on its standard port `35729`. If a different port is used, users must manually inject the LiveReload client-side script into their HTML.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure your build system or development workflow includes a file watcher that explicitly calls tiny-lr's `/changed` endpoint (via HTTP POST/GET or `lrServer.changed()`) when files are modified.","message":"tiny-lr is a notification server only; it does not include file watching capabilities. Developers must integrate it with a separate file watcher (e.g., Gulp, Grunt, Webpack, chokidar) that detects changes and then sends notifications to tiny-lr's API.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Add `app.use(bodyParser.json());` and/or `app.use(bodyParser.urlencoded({ extended: true }));` before `app.use(tinylr.middleware({ app: app }));`.","message":"When using tiny-lr as Express/Connect middleware for handling POST requests (e.g., `POST /changed`), `body-parser` (or similar middleware) is required to be mounted *before* tiny-lr's middleware in the application stack to parse the request body.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use the latest stable version (2.0.0 or higher) of `tiny-lr` to benefit from recent dependency updates and bug fixes. Avoid using abandoned forks.","message":"The package was largely unmaintained for an extended period prior to version 2.0.0, leading to forks like `mini-lr` and `tiny-lr-fork` to address issues, particularly with npm v3's flat module directory structure. While tiny-lr is now active, be aware of its historical maintenance gaps.","severity":"deprecated","affected_versions":"<2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure no other applications are running on port 35729. On Linux/macOS, use `lsof -i :35729` to identify and kill the process. On Windows, use `netstat -ano | findstr :35729` and then `taskkill /PID <PID> /F`.","cause":"Another process is already using port 35729, which is the default for LiveReload. This often happens if a previous instance of tiny-lr or another application using this port was not properly shut down.","error":"Error: listen EADDRINUSE :::35729"},{"fix":"When using `tinylr.middleware`, ensure you pass a valid Express/Connect application instance, e.g., `tinylr.middleware({ app: app })` where `app = express();`.","cause":"This error occurs if `tinylr.middleware` is called without providing an Express/Connect application instance, or if `app` is not a valid Express/Connect app.","error":"TypeError: app.use is not a function"},{"fix":"Verify that `lrServer.listen()` is called and the server is running, or that `app.use(tinylr.middleware({ app: app }))` is in your Express app's middleware stack, preceded by `body-parser` if using POST requests. Check the port being targeted.","cause":"This usually indicates that the `tiny-lr` server or its middleware is not correctly configured or running, or `body-parser` is missing for POST requests.","error":"Error: Not Found (404) for /changed endpoint"},{"fix":"Confirm tiny-lr is listening on port 35729. Check your browser's extension icon to ensure LiveReload is active for your page. Inspect browser console for `livereload.js` connection errors. Disable firewalls temporarily for testing.","cause":"The most common causes are the tiny-lr server not running on the standard port 35729, the browser extension not being enabled, or a firewall blocking the connection.","error":"Browser LiveReload extension not working/connecting"}],"ecosystem":"npm"}