{"id":19435852,"url":"https://github.com/dbushell/deno_tail_lines","last_synced_at":"2026-05-14T18:02:56.561Z","repository":{"id":146433162,"uuid":"613356430","full_name":"dbushell/deno_tail_lines","owner":"dbushell","description":"🦎 Tail the last N lines of a text file ","archived":false,"fork":false,"pushed_at":"2023-10-25T17:17:13.000Z","size":25,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-07T21:11:42.858Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dbushell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-13T12:18:02.000Z","updated_at":"2023-03-13T17:59:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"7a87f781-a9fe-4ba1-8c29-94096ffd696e","html_url":"https://github.com/dbushell/deno_tail_lines","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbushell%2Fdeno_tail_lines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbushell%2Fdeno_tail_lines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbushell%2Fdeno_tail_lines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbushell%2Fdeno_tail_lines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbushell","download_url":"https://codeload.github.com/dbushell/deno_tail_lines/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240619429,"owners_count":19830204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T15:08:14.325Z","updated_at":"2026-05-14T18:02:51.519Z","avatar_url":"https://github.com/dbushell.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦎 Deno Tail Lines\n\nRead the last N lines of a text file and return a string array.\n\n`import {tailLines} from 'https://deno.land/x/tail_lines/mod.ts';`\n\n[GitHub](https://github.com/dbushell/deno_tail_lines) / [Deno module](https://deno.land/x/tail_lines)\n\n## Usage\n\nUsing `tailLine` async function:\n\n```ts\nimport {tailLine} from 'https://deno.land/x/tail_lines/mod.ts';\nconst path = '/path/to/example.log';\nconst maxLines = 10;\nconst lines = await tailLine(path, maxLines);\n```\n\nUsing `tailLines` async iterator function:\n\n```ts\nimport {tailLines} from 'https://deno.land/x/tail_lines/mod.ts';\nconst path = '/path/to/example.log';\nconst maxLines = 10;\nconst lines: string[] = [];\nconst file = await Deno.open(path);\nfor await (const line of tailLines(file, maxLines)) {\n  lines.unshift(line);\n}\n```\n\n### Stream API\n\nThe two functions above use `TailLineStream` under the hood.\n\nTo use `TailLineStream` create an instance:\n\n```ts\nimport {TailLineStream} from 'https://deno.land/x/tail_lines/mod.ts';\nconst path = '/path/to/example.log';\nconst file = await Deno.open(path);\nconst stream = new TailLineStream(file);\nconst textDecoder = new TextDecoder();\n```\n\nThen use either the reader:\n\n```ts\nconst reader = stream.getReader();\nreader.read().then(function process({done, value}) {\n  if (done) return;\n  console.log(textDecoder.decode(value));\n  reader.read().then(process);\n});\n```\n\nOr the async iterator:\n\n```ts\nfor await (const line of stream) {\n  console.log(textDecoder.decode(line));\n}\n```\n\nYou could pipe through a `TextDecoderStream`:\n\n```ts\nconst stream = new TailLineStream(file).pipeThrough(new TextDecoderStream());\nfor await (const line of stream) {\n  console.log(line);\n}\n```\n\nBut you should just use `tailLines()` instead it will be faster.\n\n## Performance\n\nThis library works by reading the file in reverse. Useful for reading a small number of lines from the end of a very large file. For example, tailing 10 lines from the end of a 500000 line 1GB file can take \u003c 1ms on a fast drive. It is much faster than the methods below.\n\n## Using the Standard Library\n\nThe Deno standard library includes the [`TextLineStream`](https://deno.land/std@0.204.0/streams/mod.ts?s=TextLineStream) transform stream and now deprecated [`readLines`](https://deno.land/std@0.204.0/io/mod.ts?s=readLines) function. You can read all lines and slice the result.\n\n```ts\nimport {TextLineStream} from 'https://deno.land/std@0.204.0/streams/mod.ts';\nconst path = '/path/to/example.log';\nconst maxLines = 10;\nlet lines: string[] = [];\nconst file = await Deno.open(path);\nconst lines = file.readable\n  .pipeThrough(new TextDecoderStream())\n  .pipeThrough(new TextLineStream());\nfor await (const line of lines) {\n  lines.push(line);\n}\nlines = lines.slice(-maxLines);\n```\n\nPerformance balloons exponentially and is unsuitable for large files because the entire file is read through memory.\n\n## Using `tail` Unix command\n\nSpawning a `tail` process is another option.\n\n```ts\nconst path = '/path/to/example.log';\nconst maxLines = 10;\nconst command = new Deno.Command('tail', {\n  args: ['-n', String(maxLines), `${path}`]\n});\nconst {stdout} = await command.output();\nconst lines = new TextDecoder().decode(stdout).split('\\n');\n```\n\nThis technique is slower but still relatively fast compared to the standard options.\n\n* * *\n\n[MIT License](/LICENSE) | Copyright © 2023 [David Bushell](https://dbushell.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbushell%2Fdeno_tail_lines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbushell%2Fdeno_tail_lines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbushell%2Fdeno_tail_lines/lists"}