How to Collect Tweets With JavaScript and Node.js
To collect tweets with Node.js, install the apify-client package, call apidojo's Tweet Scraper V2 with an X search query, and list the items in the run's dataset.

To collect tweets with Node.js, install the apify-client package, call apidojo’s Tweet Scraper V2 with an X search query, and list the items in the run’s dataset. A short script returns posts with text, date, author and engagement at $0.40 per 1,000 tweets, with no X developer account.
This guide builds a complete Node.js collector: setup, a first run, date windows, deduplication and a CSV export. The Python version is in how to collect tweets with Python. Every other collection task is mapped in how to scrape Twitter (X) data.
What Do You Need to Collect Tweets With Node.js?
You need Node.js 18 or later, the apify-client npm package, and an Apify API token from a paid plan. Tweet Scraper V2 can’t be called through the API on the free plan (Apify). Listed below are the 3 setup steps.
- Install the client:
npm install apify-client. - Copy your API token from Apify Console.
- Store it in an environment variable:
export APIFY_TOKEN=your_token.
How Do You Run a First Collection in Node.js?
Create a client, call the actor with a searchTerms query, and read the items from its default dataset. call() starts the run and waits for it to finish.
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("apidojo/tweet-scraper").call({
searchTerms: ["from:NASA -filter:retweets"],
sort: "Latest",
maxItems: 500,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const tweet of items) {
console.log(tweet.createdAt, tweet.likeCount, tweet.text.slice(0, 80));
}
Save the file as collect.mjs so the import syntax works, then run node collect.mjs. The field names come from the actor’s output example (Apify).
How Do You Handle Tweet IDs in JavaScript?
Keep tweet IDs as strings, because JavaScript numbers can’t hold 19-digit IDs exactly. Number("1728108619189874825") changes the last digits. Use BigInt only when you need arithmetic, such as reading the creation time from an ID.
const id = BigInt("1728108619189874825");
const ms = Number((id >> 22n) + 1288834974657n);
console.log(new Date(ms).toISOString());
The ID format is explained in since: and until: explained.
How Do You Collect a Large History in Node.js?
Generate one query per month, run them in batches of 5, and store posts in a Map keyed by ID to remove duplicates. Tweet Scraper V2 accepts up to 5 batched queries per run and one concurrent run (Apify).
const queries = [];
for (let m = 0; m < 12; m++) {
const start = new Date(Date.UTC(2025, m, 1)).toISOString().slice(0, 10);
const end = new Date(Date.UTC(2025, m + 1, 1)).toISOString().slice(0, 10);
queries.push(`from:NASA since:${start} until:${end}`);
}
const tweets = new Map();
for (let i = 0; i < queries.length; i += 5) {
const run = await client.actor("apidojo/tweet-scraper").call({
searchTerms: queries.slice(i, i + 5),
includeSearchTerms: true,
sort: "Latest",
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const t of items) tweets.set(t.id, t);
}
console.log(tweets.size, "unique tweets");
Window sizes are discussed in how to scrape tweets by date range, and pagination in Twitter scraper pagination.
How Do You Save Tweets to CSV in Node.js?
Write the columns you need, wrapping text in quotes and doubling any quotes inside it.
import { writeFileSync } from "node:fs";
const esc = (v) => `"${String(v ?? "").replace(/"/g, '""')}"`;
const header = "id,url,createdAt,author,likes,text";
const rows = [...tweets.values()].map((t) =>
[t.id, t.url, t.createdAt, t.author?.userName, t.likeCount, t.text].map(esc).join(",")
);
writeFileSync("tweets.csv", [header, ...rows].join("\n"));
Other formats, including downloading a dataset directly as CSV or Excel, are covered in how to export tweets to CSV or JSON.
Questions people ask
Can you run this in the browser?
Keep the API token on a server; calling the actor from browser code would expose it.
Can you use TypeScript?
Yes, apify-client ships its own type definitions.
How do you scrape threads in Node.js?
Call apidojo/twitter-scraper-lite with conversationIds; see how to scrape a Twitter thread and all its replies.
Where do you start?
At the apidojo Twitter Scraper.