Model or dataset
pguso/rag-from-scratch avatar
pguso/rag-from-scratch

pguso/rag-from-scratch: A Node.js Walkthrough of Retrieval-Augmented Generation Without Cloud APIs

Demystify RAG by building it from scratch. Local LLMs, no black boxes - real understanding of embeddings, vector search, retrieval, and context-augmented generation.

1,629 stars195 forksJavaScriptMIT

At a glance

What is it?
This MIT-licensed JavaScript repository teaches RAG by building each stage by hand with local LLMs. It is a teaching artifact, not a retrieval library, and the numbered example directories are the product.
Who is it for?
Adopt this repository if you are a JavaScript developer who wants to see every stage of a RAG pipeline as readable code, or if you are preparing to teach retrieval concepts to a team. Do not adopt it as the retrieval layer of a production service: there is no package, no release, no API surface and no persistence story beyond what the examples demonstrate.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap this repository fills: RAG as a sequence of readable steps

Most RAG material arrives in one of two shapes. Either it is a framework where retrieval, chunking and generation are hidden behind a chain abstraction, or it is a diagram with no runnable code underneath it. The README states the project's intent directly: "No black boxes. No cloud APIs. Just clear explanations, simple examples, and local code you fully understand." That sentence is the whole design brief.

The audience is a JavaScript developer who has used an LLM API but has never written a cosine similarity function, never split a document by hand, and never built an index. The repository assumes Node.js and a local model runtime, and it assumes you are willing to read code rather than import it. If you already know how top-k retrieval works, the early examples will feel slow. That is the intended pace, not an accident.

The ten-stage pipeline as the repository lays it out

The README enumerates the pipeline in ten numbered steps: knowledge requirements, data loading, text splitting and chunking, embedding, vector store, retrieval, post-retrieval re-ranking, query preprocessing and embedding normalization, augmentation, and generation. The examples directory mirrors this ordering, which matters because it means each folder is a self-contained lesson rather than a module you import into the next.

The numbering in the README is not perfectly sequential. The learning path lists section 0 as examples/00_how_rag_works/, then jumps to examples/02_data_loading/ for data loading, then examples/03_text_splitting_and_chunking/, examples/04_intro_to_embeddings/02_generate_embeddings/, examples/05_building_vector_store/01_in_memory_store/, and examples/06_retrieval_strategies/ with numbered subfolders for basic retrieval, query preprocessing, hybrid search and multi-query retrieval. There is no visible examples/01_ directory in the material supplied. Treat the folder names as the authoritative order, not the README's section numbers.

Each example ships with three files: example.js, CODE.md and CONCEPT.md. That split is the most useful structural decision in the repository. CONCEPT.md carries the theory, CODE.md walks the implementation, and example.js is the thing you actually run. The README's own claim about the introductory example is that it shows "a minimal, simplified end-to-end RAG flow in under 70 lines of code."

What runs locally, and what node-llama-cpp implies

The topics list names node-llama-cpp, which is the binding the project uses to run models on your own machine instead of calling a hosted endpoint. The README repeats the no-cloud-API position in its opening paragraph. The practical consequence is that embeddings and generation both come from a model you supply and load locally.

That choice has costs the README does not dwell on. Local inference means the model file has to exist on disk, the runtime has to compile or install for your platform, and generation speed depends on your hardware rather than on a vendor's capacity. The repository does not publish benchmark numbers, and none are claimed here. What the material does establish is the dependency direction: install node-llama-cpp, point it at a model, and the examples can then produce embeddings and completions without network calls.

The upside is reproducibility. A tutorial that depends on a hosted embedding endpoint can break when that endpoint changes, and the reader cannot inspect what the model did. A tutorial that runs locally can be re-run offline and the vector values can be printed and compared. For a project whose stated goal is demystification, that is the right trade.

Getting the examples running: the commands the README implies

The README does not include a copy-paste installation block in the material supplied, so the exact package.json scripts cannot be confirmed from it. What can be confirmed is the shape of the workflow. You clone the repository, install dependencies with npm install, and then run an individual example with node against its file path.

The concrete entry points are the example.js files, one per stage. The most complete single file named in the README is examples/06_retrieval_strategies/01_basic_retrieval/showcase.js, which the README describes as showing "everything you learned so far in action." If you want one command to judge whether the project is worth your time, that is the file to run first, after installing node-llama-cpp and making a model available.

The configuration surface visible in the material is conceptual rather than key-based. Chunk size and overlap are introduced in the text splitting stage. Top-k is introduced in basic retrieval. Weighting between vector and keyword signals appears in hybrid search. Reciprocal rank fusion and weighted fusion appear in multi-query retrieval. The README names these as concepts the examples cover, but it does not publish the literal config keys, so expect to read example.js to find the parameter names. Anyone who needs a documented config schema before running code will be frustrated here.

The retrieval strategies are where the repository earns its place

The first five stages are groundwork. Chunking, embedding and an in-memory vector store are things most developers can guess at. The material becomes worth reading at examples/06_retrieval_strategies/, which the README splits into four numbered subfolders: 01_basic_retrieval, 02_query_preprocessing, 03_hybrid_search and 04_multi_query_retrieval.

Hybrid search is described as combining vector similarity with keyword signals, with BM25 named explicitly alongside embeddings and weighted scoring. Multi-query retrieval goes further: decomposing a complex query into sub-queries, running them in parallel, and fusing the result lists with reciprocal rank fusion or weighted fusion, then deduplicating. These are the parts of a real retrieval system that a naive tutorial skips, and the README lists them as covered topics rather than as future work.

Query preprocessing sits between them, covering normalization, stopword removal and query cleaning, with vector stability named as the goal. Whether aggressive stopword removal helps or hurts a given embedding model is genuinely debatable, and the repository's position on that debate is not visible in the supplied material. The example exists; the argument for it does not appear here.

Where this repository is the wrong tool

There is no package to install. No npm package name appears in the material, no releases are listed, and the repository is a collection of example directories. If you need a retrieval layer inside a running service, you cannot import this and move on. You would be copying code out of example.js files and maintaining it yourself.

The vector store is described as in-memory. That is fine for a lesson on nearest-neighbor search and wrong for anything that must survive a restart or hold more documents than your process memory allows. The material does not describe persistence, sharding, or an on-disk index format.

Local inference is a second constraint. If your deployment target is a container without a GPU, or a serverless function with a size limit, running a model locally is a poor fit regardless of how good the tutorial is. The no-cloud-API stance is a teaching decision that becomes an infrastructure decision the moment you try to ship it.

Finally, the project is educational by its own labelling. The topics list includes "educational" and "tutorial." Nothing in the material suggests an intent to provide stability guarantees, semantic versioning, or backward compatibility across examples.

How it differs from a RAG framework

The natural comparison is LangChain.js. The difference is not feature count, it is where the abstraction sits. A framework gives you a retriever interface, a document loader interface and a vector store interface, and you compose them. The internals of similarity scoring and index traversal are the framework's problem, not yours.

This repository inverts that. The README's phrase "local code you fully understand" is the design constraint. Every stage is written out so that the reader can see the loop, the distance calculation and the prompt assembly. The cost is that nothing is reusable without extraction. The benefit is that when retrieval returns the wrong chunk, you know which line produced it because you wrote the equivalent of that line in an earlier example.

For a team deciding between the two, the question is whether the bottleneck is shipping speed or debugging ability. A framework shortens the first path. This repository shortens the second. They are not substitutes.

Maintenance, licence and what to verify before you invest

The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the standard permissive arrangement, and it places no copyleft obligation on code you derive from the examples. This is a description of the licence text, not legal advice; if you are folding example code into a product, have counsel read the actual LICENSE file in the repository.

There are no releases listed, so there is no version to pin and no changelog to read for breaking changes. The last push recorded is 2026-03-11, which tells you the repository was active at that point but says nothing about how often examples are revised. If you track main, expect the examples to move under you.

The upgrade cost is mostly environmental rather than API-level. node-llama-cpp tracks upstream llama.cpp, and local inference bindings are sensitive to Node version and platform toolchain. Verifying that the binding installs and loads a model on your machine is the first real test, and it is the step most likely to consume an afternoon.

One more thing to check before you start: the README's learning path lists an examples/02_data_loading/ directory while the numbered sections around it skip from 0 to 2. Confirm which folders exist on the branch you clone rather than trusting the section numbers, and read CODE.md alongside example.js, since the repository splits explanation from implementation on purpose.

Editorial conclusion

Adopt this repository if you are a JavaScript developer who wants to see every stage of a RAG pipeline as readable code, or if you are preparing to teach retrieval concepts to a team. Do not adopt it as the retrieval layer of a production service: there is no package, no release, no API surface and no persistence story beyond what the examples demonstrate. Before committing time, check the examples directory listing for the stage you care about, confirm that node-llama-cpp installs cleanly against your Node version and platform, and read examples/06_retrieval_strategies/01_basic_retrieval/showcase.js to see how far the material actually goes.

Official sources

  1. Issues
  2. License: MIT
  3. pguso/rag-from-scratch on GitHub
  4. README
Community notes

Community notes