{"id":14092,"library":"tail","title":"Node.js File Tailing Utility","description":"tail is a zero-dependency Node.js module designed for monitoring and reading file changes in real-time, similar to the `tail -f` command-line utility. It provides an event-driven API to react to new lines appended to a file. The current stable version is 2.2.6. Recent releases indicate a consistent maintenance cadence with bug fixes and minor feature additions (e.g., `nLines` flag in v2.2.0). A key differentiator is its minimal dependency footprint and its robust handling of file rotation and renaming scenarios through the `follow` option, mimicking `tail -F`. It transitioned from CoffeeScript to pure ES6 in December 2020, ensuring modern JavaScript compatibility and performance. It supports various configurations for line separators, file watching options, and starting positions.","status":"active","version":"2.2.6","language":"javascript","source_language":"en","source_url":"git://github.com/lucagrulla/node-tail","tags":["javascript","tail","file","logs"],"install":[{"cmd":"npm install tail","lang":"bash","label":"npm"},{"cmd":"yarn add tail","lang":"bash","label":"yarn"},{"cmd":"pnpm add tail","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Tail is a named export. While the CommonJS `require('tail').Tail` pattern works, prefer named ESM imports for clarity and tree-shaking benefits.","wrong":"import Tail from 'tail'","symbol":"Tail","correct":"import { Tail } from 'tail'"},{"note":"When using CommonJS, access the `Tail` constructor as a named export from the module. Direct `require('tail')` returns the module object, not the constructor itself.","wrong":"const Tail = require('tail')","symbol":"Tail (CommonJS)","correct":"const { Tail } = require('tail')"},{"note":"This pattern is explicitly shown in the README and remains a valid way to import the `Tail` constructor in CommonJS environments.","symbol":"Tail (Legacy CommonJS)","correct":"const Tail = require('tail').Tail"}],"quickstart":{"code":"const { Tail } = require('tail');\nconst path = require('path');\nconst fs = require('fs');\n\nconst tempFilePath = path.join(__dirname, 'log.txt');\n\n// Create a dummy log file for demonstration\nfs.writeFileSync(tempFilePath, 'Initial log entry\\n');\n\ntry {\n  const tail = new Tail(tempFilePath, { fromBeginning: true });\n\n  tail.on('line', function(data) {\n    console.log('New line:', data);\n  });\n\n  tail.on('error', function(error) {\n    console.error('Tail Error:', error);\n  });\n\n  // Append some lines after a delay to simulate log activity\n  let counter = 0;\n  const interval = setInterval(() => {\n    counter++;\n    fs.appendFileSync(tempFilePath, `Appended line ${counter}\\n`);\n    if (counter >= 3) {\n      clearInterval(interval);\n      setTimeout(() => {\n        console.log('Stopping tail...');\n        tail.unwatch();\n        fs.unlinkSync(tempFilePath); // Clean up temp file\n      }, 1000);\n    }\n  }, 500);\n\n} catch (ex) {\n  console.error('Failed to initialize Tail:', ex);\n  if (fs.existsSync(tempFilePath)) {\n    fs.unlinkSync(tempFilePath); // Clean up temp file on error too\n  }\n}","lang":"javascript","description":"This quickstart demonstrates how to install `tail`, initialize it for a temporary log file, listen for new lines, handle potential errors, and simulate log activity by appending data. It also shows how to stop watching and clean up resources."},"warnings":[{"fix":"Carefully choose between `fromBeginning` (tail entire file) and `nLines` (tail from the last N lines). Do not set both if you expect `nLines` to take effect.","message":"The `fromBeginning` option takes precedence over `nLines`. If both are set, `fromBeginning` will be honored, and `nLines` will be ignored.","severity":"gotcha","affected_versions":">=2.2.0"},{"fix":"Always wrap `Tail` constructor calls in a `try...catch` block to handle file existence or path validity errors gracefully. Ensure the file exists before instantiation.","message":"The `Tail` constructor throws a synchronous exception if the specified file path is missing or invalid, preventing initialization.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If automatic re-watching is desired for scenarios like log rotation (simulating `tail -F`), ensure `follow` is set to its default value of `true` or explicitly configure it.","message":"Setting `follow: false` (default is `true`) will cause an `error` event to be emitted if the file is moved, renamed, or logrotated, instead of automatically re-watching the new file.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Only set `useWatchFile: true` if you have specific reasons or are troubleshooting issues with `fs.watch` behavior on your platform. Generally, allow the library to make the default choice.","message":"Forcing `useWatchFile: true` will bypass the library's internal logic for choosing between `fs.watch` and `fs.watchFile`, potentially leading to different performance characteristics or platform-specific issues.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'2.2.6':54 '2020':108 'addit':68 'api':39 'append':45 'bug':63 'cadenc':61 'chang':19 'coffeescript':102 'command':30 'command-lin':29 'compat':112 'configur':118 'consist':59 'current':50 'decemb':107 'depend':10,80 'design':13 'differenti':76 'driven':38 'e.g':69 'ensur':109 'es6':105 'event':37 'event-driven':36 'f':28,98 'featur':67 'file':2,18,48,87,122,130 'fix':64 'flag':71 'follow':94 'footprint':81 'handl':85 'indic':57 'javascript':111,128 'key':75 'line':31,44,120 'log':131 'mainten':60 'mimick':96 'minim':79 'minor':66 'modern':110 'modul':12 'monitor':15 'new':43 'nline':70 'node.js':1,11 'option':95,124 'perform':114 'posit':127 'provid':34 'pure':104 'react':41 'read':17 'real':22 'real-tim':21 'recent':55 'releas':56 'renam':90 'robust':84 'rotat':88 'scenario':91 'separ':121 'similar':24 'stabl':51 'start':126 'support':116 'tail':3,5,27,97,129 'time':23 'transit':100 'util':4,32 'v2.2.0':73 'various':117 'version':52 'watch':123 'zero':9 'zero-depend':8","created_at":"2026-04-20T01:57:53.574146+00:00","updated_at":"2026-04-20T01:57:53.574146+00:00","problems":[{"fix":"Verify that the file path is correct and accessible. Wrap the `Tail` constructor call in a `try...catch` block to handle this synchronous error: `try { new Tail('missingFile.txt') } catch (ex) { console.error(ex); }`","cause":"The file path provided to the `Tail` constructor is invalid, or the file does not exist at the specified location.","error":"Tail constructor will throw an Exception and won't initialize."},{"fix":"For CommonJS, use `const { Tail } = require('tail');` or `const Tail = require('tail').Tail;`. For ESM, use `import { Tail } from 'tail';`.","cause":"Attempting to import or require the `Tail` constructor incorrectly, often by trying to use a default import with ESM or directly requiring the module without accessing the `.Tail` property in CommonJS.","error":"TypeError: Tail is not a constructor"},{"fix":"Always register an error listener on the `tail` instance to prevent unhandled promise rejections or process crashes: `tail.on('error', (err) => { console.error('Tail encountered an error:', err); });`","cause":"The `tail` instance encountered an issue (e.g., file system error, underlying read error, or `follow: false` on file rename) and emitted an 'error' event, but no listener was registered to handle it.","error":"Unhandled 'error' event"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.1.12","cli_name":"","cli_version":null,"type":"library","homepage":"https://www.lucagrulla.com/node-tail","github":"https://github.com/lucagrulla/node-tail","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/tail","openapi_spec":null,"status_page":null,"smithery":null,"categories":["observability"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}