LlamaIndex Tutorial (TypeScript): handling long documents for beginners
This tutorial shows you how to ingest long documents in TypeScript with LlamaIndex, split them into chunks, build a searchable index, and query it without blowing past model context limits. You need this when your source material is too large to send to an LLM in one shot, which is the normal case for PDFs, policy docs, contracts, and internal knowledge bases.
What You'll Need
- •Node.js 18+
- •A TypeScript project with
ts-nodeortsx - •
llamaindexinstalled - •An OpenAI API key
- •A long text document saved locally, for example
./data/handbook.txt - •Basic familiarity with async/await and ES modules
Install the package:
npm install llamaindex
Set your API key:
export OPENAI_API_KEY="your-key-here"
Step-by-Step
- •Start by loading your long document from disk. For beginners, plain text is the easiest place to start because it removes PDF parsing noise and lets you focus on the indexing pipeline.
import fs from "node:fs";
import path from "node:path";
import { Document } from "llamaindex";
const filePath = path.join(process.cwd(), "data", "handbook.txt");
const text = fs.readFileSync(filePath, "utf-8");
const document = new Document({
text,
metadata: {
source: "handbook.txt",
},
});
console.log(`Loaded document with ${text.length} characters`);
- •Next, split the document into chunks. Long documents need chunking so retrieval can pull only the relevant sections instead of sending the entire file to the model.
import { SentenceSplitter } from "llamaindex";
const splitter = new SentenceSplitter({
chunkSize: 1024,
chunkOverlap: 150,
});
const chunks = splitter.splitText(document.text);
console.log(`Created ${chunks.length} chunks`);
console.log(chunks[0].slice(0, 200));
- •Build a vector index from those chunks. This is the core move: each chunk gets embedded, stored, and later retrieved by semantic similarity.
import { Document as LlamaDocument, VectorStoreIndex } from "llamaindex";
const docs = chunks.map(
(chunk) =>
new LlamaDocument({
text: chunk,
metadata: {
source: "handbook.txt",
},
}),
);
const index = await VectorStoreIndex.fromDocuments(docs);
console.log("Vector index built");
- •Create a query engine and ask a question against the long document. The engine retrieves only the most relevant chunks, then uses them as context for the answer.
const queryEngine = index.asQueryEngine({
similarityTopK: 3,
});
const response = await queryEngine.query({
query: "What is the leave approval process?",
});
console.log(String(response));
- •Put it together in one runnable script. This version is what you should actually keep around while learning because it shows the full flow from file load to answer.
import fs from "node:fs";
import path from "node:path";
import {
Document,
SentenceSplitter,
VectorStoreIndex,
} from "llamaindex";
async function main() {
const filePath = path.join(process.cwd(), "data", "handbook.txt");
const text = fs.readFileSync(filePath, "utf-8");
const splitter = new SentenceSplitter({
chunkSize: 1024,
chunkOverlap: 150,
});
const chunks = splitter.splitText(text);
const docs = chunks.map(
(chunk) =>
new Document({
text: chunk,
metadata: { source: "handbook.txt" },
}),
);
const index = await VectorStoreIndex.fromDocuments(docs);
const queryEngine = index.asQueryEngine({ similarityTopK: 3 });
const response = await queryEngine.query({
query: "Summarize the key policy rules in this document.",
});
console.log(String(response));
}
main().catch(console.error);
Testing It
Run the script against a real long file and make sure it returns an answer that references only content from that file. If you get empty or irrelevant results, reduce chunkSize slightly or increase similarityTopK to retrieve more context.
Also check that your API key is available in the same shell session where you run Node. If indexing succeeds but queries fail, inspect whether the document is actually long enough to require chunking and whether your question matches language used in the source.
A good sanity test is to ask for something specific like a section name, policy rule, or date range. If the response can point back to those details consistently across multiple runs, your pipeline is working.
Next Steps
- •Add metadata filters so you can search only specific departments, products, or document types
- •Replace plain text loading with PDF ingestion using LlamaIndex readers
- •Persist the vector store so you do not rebuild embeddings on every startup
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit