
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
readlineiter
Advanced tools
Read text file (remote over HTTP(S) or local) line by line as async iterator, with Node, browsers and Deno
Read text file (remote over HTTP(S) or local) line by line as async iterator, with Node, browsers and Deno.
This GitHub monorepo hosts 6 npm packages and 1 Deno module. They all serve a similar, simple purpose: read text file line by line and return an asynchronous iterable iterator of strings. They all try to be efficient and fast, and are written in TypeScript. However, their environment / platforms and exact purpose, features and behavior differ.
TLDR: read the "Purpose & environment" table, pick the package you need, have a look at the Usage section, know at least a little bit about JavaScript's async / await, and go ahead to use them.
| Package / Module Name | Rec? | Fetch remote file over HTTP(S) | Read local file | Version | |||
|---|---|---|---|---|---|---|---|
| fetchline | 👍 | ✅ | ✅ | ||||
| nodefetchline | 👍 | ✅ | |||||
| isomorphic-fetchline | ✅ | ✅ | |||||
| naivefetchline | ✅ | ✅ | |||||
| getfileline | ✅ | ||||||
| readlineiter | 👍 | ✅ | |||||
| readlineiter for Deno | 👍 | ✅ |
If you are not sure, just use the recommended one that has the correct environment and purpose you need.
Tested:
npm install fetchline
import fetchline from 'fetchline'
const lineIterator =
fetchline('https://raw.githubusercontent.com/tomchen/fetchline/main/testfile/crlf_finalnewline')
// This is the same as:
// fetchline(
// 'https://raw.githubusercontent.com/tomchen/fetchline/main/testfile/crlf_finalnewline',
// {
// includeLastEmptyLine: true,
// encoding: 'utf-8',
// delimiter: /\r?\n/g,
// }
// )
;(async () => {
for await (const line of lineIterator) {
// do something with `line`
}
})()
Change 'fetchline' to nodefetchline, isomorphic-fetchline, or naivefetchline if you use these packages instead.
For Deno: import fetchline from 'https://github.com/tomchen/fetchline/blob/main/packages/fetchline/src/index.ts'
Change the import line to syntax like const nodefetchline = require('nodefetchline') if you use nodefetchline or isomorphic-fetchline package in Node's CommonJS.
For browsers:
<script src="https://unpkg.com/fetchline/dist/umd"></script>
<script>
fetchline(...) // same as above
</script>
These four packages have exactly the same interface (parameters and return value):
| Parameter Name | Required? | Type | Default Value | Description |
|---|---|---|---|---|
filepath | Required | string | N/A | URL or path of the text file |
options | Optional | object | {} | options, including the following three |
options.includeLastEmptyLine | Optional | boolean | true | Should it count the last empty line? |
options.encoding | Optional | string | 'utf-8' | File encoding |
options.delimiter | Optional | string or RegExp | /\r?\n/g | Line (or other item)'s delimiter / separator. NOTE: do not set it as something like /\r\n|\n|\r/g, it causes trouble when one of the chunks of a CRLF (\r\n)-EOL file ends with CR (\r) |
Return value: { AsyncIterableIterator<string> } An asynchronous iterable iterator containing each line in string from the text file
They have similar interface as the aforementioned fetchline, nodefetchline, isomorphic-fetchline, and naivefetchline, but do not have the second parameter, options, and everything options contains.
npm install readlineiter
import readlineiter from 'readlineiter' // For Deno: import readlineiter from 'https://raw.githubusercontent.com/tomchen/fetchline/main/packages/readlineiter-deno/mod.ts'
const lineIterator = readlineiter('./crlf_finalnewline')
;(async () => {
for await (const line of lineIterator) {
// do something with `line`
}
})()
| ASAP | 0 dependency | TypeScript | |
|---|---|---|---|
| fetchline | ✅ | ✅ | ✅ |
| nodefetchline | ✅ | ✅ | ✅ |
| isomorphic-fetchline | ✅ | ✅ | .d.ts |
| naivefetchline | ❌ | ✅ | ✅ |
| getfileline | ✅ | ✅ | ✅ |
| readlineiter | ✅ | ✅ | ✅ |
| readlineiter for Deno | ✅ | ✅ | ✅ |
ASAP:
0 dependency: no external non-dev dependency for npm packages. Note that:
http and https, or fsreadline native lib directly thus are just wrappers, but other packages here use own low-level methodbufio.ts.TypeScript: the source code is in TypeScript, except for isomorphic-fetchline's source which is in JavaScript but has type definition (.d.ts).
As for the production / dist files, these packages are all compiled into different module versions where possible: Node.js' Common.js (which uses require()), ES Module (native JS module with import), and minified UMD that is good for browser.
filepath parameter | includeLastEmptyLine option | encoding option | delimiter option | Return AsyncIterableIterator<string> | |
|---|---|---|---|---|---|
| fetchline | ✅ | ✅ | ✅ | ✅ | ✅ |
| nodefetchline | ✅ | ✅ | ✅ | ✅ | ✅ |
| isomorphic-fetchline | ✅ | ✅ | ✅ | ✅ | ✅ |
| naivefetchline | ✅ | ✅ | ✅ | ✅ | ✅ |
| getfileline | ✅ | ❌, always doesn't | ❌, always utf-8 | ❌, always EOL detected by readline | ✅ |
| readlineiter | ✅ | ❌, always doesn't | ❌, always utf-8 | ❌, always EOL detected by readline | ✅ |
| readlineiter for Deno | ✅ | ❌, always does | ❌, always utf-8 | ❌, always EOL detected by bufio.ts | ✅ |
getfileline and readlineiter's delimiter is EOL character detected by readline native module with its crlfDelay option set to Infinity.
async / awaitOf course, you should at least know a little bit about async / await, await asyncIterator.next() or for await of before using the packages here. If you don't, click the links to read the article from MDN Web Docs. Basically, you can do this:
;(async () => {
for await (const line of lineIterator) {
// do something with `line`
}
})()
Or this:
;(async () => {
let line
let isDone
while (1) {
;({ value: line, done: isDone } = await lineIterator.next())
// do something with `line`
if (isDone) {
break
}
}
})()
These packages, especially 'fetchline' (the first one) for browsers, could be helpful for line-delimited JSON (aka. ndjson (Newline Delimited JSON), JSON Lines) parsing. You could write something like:
import fetchline from 'fetchline'
const lineIterator = fetchline(lineDelimitedJsonUrl)
;(async () => {
for await (const line of lineIterator) {
const lineJson = JSON.parse(line)
// do something with `lineJson`
}
})()
This is a Lerna powered monorepo with mixed code (TypeScript / JavaScript), mixed module version (CommonsJS, ES Module, UMD) and cross-environment (Node.js, Deno, browsers) support, automated tests with GitHub Actions CI. Look at the root package.json and individual packages' package.json for available scripts, to get started, yarn then yarn bootstrap. You could also use the repo as an example of Lerna monorepo.
FAQs
Read text file (remote over HTTP(S) or local) line by line as async iterator, with Node, browsers and Deno
The npm package readlineiter receives a total of 85 weekly downloads. As such, readlineiter popularity was classified as not popular.
We found that readlineiter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.