<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bjorn-Donald Bassey</title>
    <description>The latest articles on DEV Community by Bjorn-Donald Bassey (@bjorndonald_bassey_c126c).</description>
    <link>https://dev.to/bjorndonald_bassey_c126c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2164090%2F3521f2c0-313a-4ef1-b76b-f8721fa6bfac.jpg</url>
      <title>DEV Community: Bjorn-Donald Bassey</title>
      <link>https://dev.to/bjorndonald_bassey_c126c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bjorndonald_bassey_c126c"/>
    <language>en</language>
    <item>
      <title>The point of Memoisation in React</title>
      <dc:creator>Bjorn-Donald Bassey</dc:creator>
      <pubDate>Mon, 02 Feb 2026 07:16:21 +0000</pubDate>
      <link>https://dev.to/bjorndonald_bassey_c126c/the-point-of-memoisation-in-react-4e82</link>
      <guid>https://dev.to/bjorndonald_bassey_c126c/the-point-of-memoisation-in-react-4e82</guid>
      <description>&lt;p&gt;You often hear people's advice to React developers to implement memoization by using useMemo or useCallback to improve the performance of your React project. Well, the simplest answer is that it reduces the number of re-renders your application has to make for a React component. But the much longer answer requires an understanding of the heap allocation that happens with your computer's memory. The heap is a body of storage where larger blocks of data can persist with a non-deterministic lifecycle as opposed to the stack, which is usually tied to a function or the main process, where the lifecycle is deterministic (tied to the operation of the function). &lt;/p&gt;

&lt;p&gt;While the stack is usually very easy to manage by the CPU, managing data on the heap can be very expensive. This can be divided into: &lt;br&gt;
Allocation of data into blocks of memory, &lt;br&gt;
Deallocation of blocks of memory to free them for other users, &lt;br&gt;
Synchronisation, which manages the ownership and usage of the data within certain memory locations across multiple threads to avoid data races and simultaneous allocation/deallocations, &lt;br&gt;
and fragmentation, which involves breaking apart contiguous blocks of memory to fit data of different sizes. This can lead to a lot of free memory blocks that can’t be used.&lt;/p&gt;

&lt;p&gt;What programmers need to understand is that all these operations are costly. The programmer needs to decide when and where these costs occur so they don’t have a negative effect on a user's experience with their application.&lt;/p&gt;

&lt;p&gt;How does this relate to JavaScript?&lt;br&gt;
JavaScript can be described as an interpreted language, which means the programmer does not have any control over the allocation or deallocation of the heap. Languages like these have their own garbage collectors as opposed to low-level languages like C or C++. React components are simply functions that re-run. That means those costly heap management operations are also going on each rerun. React will rerender a component when it notices differences in its props, state, or changes in a hook. Every time the React function reruns, every variable or function gets a new memory address, which costs cpu cycles and possibly leads to fragmentation.&lt;/p&gt;

&lt;p&gt;But there are some sure-fire ways to avoid unintended memory and CPU usage when building your React project. The keyword is Stable references.&lt;/p&gt;

&lt;p&gt;Usually, primitive values like strings, integers, or booleans are compared based on their values, but objects are compared based on their memory addresses. Say you pass an inline function as a prop to a child component like so: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;function Parent() { &lt;br&gt;
    const handleClick = () =&amp;gt; console.log("Clicked!"); &lt;br&gt;
    return &amp;lt;Child onClick={handleClick} /&amp;gt;; &lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
An inline function creates a new memory reference every time it runs. The child component will constantly re-render because the memory address keeps changing. This is the case with variables that are objects in the Component. They will need to get a memory address on the heap every time the component rerenders.&lt;/p&gt;

&lt;p&gt;So, useCallback ensures that the memory address of the functions remain thesame between renders unless necessary,&lt;/p&gt;

&lt;p&gt;const handleClick = useCallback(() =&amp;gt; { console.log("Clicked!");},[])&lt;/p&gt;

&lt;p&gt;useMemo maintains a single memory address for objects or arrays between renders unless necessary. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;const object = useMemo(() =&amp;gt; ({ color: 'blue' }), []);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However, using memoization too much can be detrimental to your project performance due to the amount of resources used for the diff operations&lt;/p&gt;

&lt;p&gt;Ref objects are the ultimate strategy for ensuring stability. These are plain JavaScript objects that will retain the same memory address for the whole lifecycle of the component. A change to the ref value (ref.current) doesn’t trigger a re-render.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const ref = useRef(0)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I am on a mission to understand how to get more value from systems with limited memory and compute resources. This was just me relating some things I learnt back to a framework I use frequently at work. I’d love to hear about any bits of knowledge to better understand the frameworks we use. &lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>javascript</category>
      <category>performance</category>
      <category>react</category>
    </item>
    <item>
      <title>Find the Maximum Area possible given different vertical lines on X-Axis (Leetcode Problem Analysis)</title>
      <dc:creator>Bjorn-Donald Bassey</dc:creator>
      <pubDate>Sat, 04 Oct 2025 14:58:00 +0000</pubDate>
      <link>https://dev.to/bjorndonald_bassey_c126c/find-the-maximum-area-possible-given-different-vertical-lines-on-x-axis-leetcode-problem-analysis-2h9o</link>
      <guid>https://dev.to/bjorndonald_bassey_c126c/find-the-maximum-area-possible-given-different-vertical-lines-on-x-axis-leetcode-problem-analysis-2h9o</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem Statement: Given an array with n numbers representing the heights of vertical lines on an x-axis, find the maximum area that can be created with two lines from your array. (Difficulty: Medium)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;br&gt;
An array of integers representing different heights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
A single integer: the max area.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brute Force Approach:&lt;/strong&gt;&lt;br&gt;
I first considered testing the area for every pair of values using a shifting center algorithm but that would simply take too long. The time complexity seemed too close to On^2. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two-Pointer Approach:&lt;/strong&gt;&lt;br&gt;
So, the strategy was changed to invlove to pointers which will gradually move towards the center of the array while the area is being tested to find the max at each loop iteration. I attempted to halve the number of loop iterations by moving both pointers in each iteration but I getting out of bounds errors. So, I had to reevaluate my solution's requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized Two-Pointer Approach:&lt;/strong&gt;&lt;br&gt;
I came to the realization that what the solution required was finding the longest lines which were farthest apart as soon as possible, so I decided that to move the pointers based on which value was higher at a loop iteration.&lt;/p&gt;

&lt;p&gt;Time complexity: O(n)&lt;/p&gt;

&lt;p&gt;Here is the Code in JAVA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public int maxArea(int[] h) {
        int n = h.length, i=0, max=Integer.MIN_VALUE, a=0,b=n-1;
        if(n==1){
            return h[0];
        }
        while(b&amp;gt;a){
            if(h[a]&amp;lt;h[b]){
                int aa = h[a]*(b-a);
                if(max&amp;lt;aa) max=aa;
                a++;
            } else {
                int aa=h[b]*(b-a);
                if(max&amp;lt;aa) max=aa;
                b--;
            }
        }

        return max;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>leetcode</category>
      <category>java</category>
    </item>
    <item>
      <title>Supercharging Retrieval-Augmented Generation with NodeRAG: A Graph-Centric Approach</title>
      <dc:creator>Bjorn-Donald Bassey</dc:creator>
      <pubDate>Mon, 26 May 2025 04:19:21 +0000</pubDate>
      <link>https://dev.to/bjorndonald_bassey_c126c/supercharging-retrieval-augmented-generation-with-noderag-a-graph-centric-approach-ggc</link>
      <guid>https://dev.to/bjorndonald_bassey_c126c/supercharging-retrieval-augmented-generation-with-noderag-a-graph-centric-approach-ggc</guid>
      <description>&lt;p&gt;&lt;strong&gt;Large Language Models (LLMs)&lt;/strong&gt; continue to break new ground in complex reasoning tasks. It often feels like a new frontier model tops the leaderboard for reasoning benchmarks every other week. A major contributor to these advancements is the evolution of &lt;strong&gt;retrieval mechanisms&lt;/strong&gt;—particularly those powered by &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First introduced by the &lt;strong&gt;Meta AI team&lt;/strong&gt; (&lt;a href="https://arxiv.org/abs/2005.11401" rel="noopener noreferrer"&gt;Lewis et al., 2020&lt;/a&gt;), RAG was designed to improve factual consistency in language model outputs by accessing external corpora during inference. This allows models to deliver more domain-specific, up-to-date, and grounded responses.&lt;/p&gt;

&lt;p&gt;Today, tech giants like Google and OpenAI implement RAG differently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google’s Vertex AI Search&lt;/strong&gt; combines semantic and keyword (hybrid) search with a re-ranking mechanism to serve the most relevant results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI&lt;/strong&gt;, on the other hand, embeds RAG directly into the model's runtime when tools and file uploads are enabled. Additionally, OpenAI orchestrates tool usage intelligently with its &lt;strong&gt;Responses API&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, for independent developers and smaller teams, replicating this level of RAG infrastructure is costly. That’s why it’s crucial to explore &lt;strong&gt;open-source innovations&lt;/strong&gt; that democratize access to advanced RAG capabilities.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;NodeRAG&lt;/strong&gt;: a powerful, graph-based RAG framework designed to optimize retrieval by leveraging heterogeneous graph structures. The key contributions of this method can be summarized into three key aspects&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bo674e7dd44fiifcd66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bo674e7dd44fiifcd66.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj216lgebv5vqw17rksno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj216lgebv5vqw17rksno.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2gosdznnihvvjjkqqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2gosdznnihvvjjkqqt.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is NodeRAG?
&lt;/h2&gt;

&lt;p&gt;NodeRAG is a &lt;strong&gt;graph-centric RAG framework&lt;/strong&gt; designed to address limitations in traditional RAG systems, especially when dealing with &lt;strong&gt;multi-hop reasoning&lt;/strong&gt; and &lt;strong&gt;summary-level queries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While earlier graph-based RAG methods showed promise, they often overlooked the &lt;strong&gt;design of the graph structure itself&lt;/strong&gt;. NodeRAG changes that by deeply integrating graph methodologies throughout the indexing and searching process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56qgmtul11xv95qu3d48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56qgmtul11xv95qu3d48.png" alt="Illustration for NaiveRAG, GraphRAG, HippoRAG, LightRAG, NodeRAG" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At its core, NodeRAG builds a &lt;strong&gt;heterograph&lt;/strong&gt;—a graph made up of different node types, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entities (N)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relationships (R)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semantic Units (S)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attributes (A)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;High-level Elements (H)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overviews (O)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text Chunks (T)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These nodes form a richly connected structure that encapsulates, summarizes, and enhances the original corpus—leading to &lt;strong&gt;fine-grained&lt;/strong&gt;, &lt;strong&gt;context-aware&lt;/strong&gt;, and &lt;strong&gt;explainable retrieval&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  NodeRAG Pipeline: From Corpus to Graph
&lt;/h2&gt;

&lt;p&gt;The NodeRAG pipeline is split into two main phases: &lt;strong&gt;graph indexing&lt;/strong&gt; and &lt;strong&gt;graph searching&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Graph Indexing
&lt;/h3&gt;

&lt;p&gt;This phase constructs the heterograph and enriches it with multiple layers of semantic information.&lt;/p&gt;

&lt;h4&gt;
  
  
  a. Graph Decomposition
&lt;/h4&gt;

&lt;p&gt;Text is broken down using an LLM into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Units (S)&lt;/strong&gt;: Paraphrased summaries of local events or ideas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entities (N)&lt;/strong&gt;: Named objects or people.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationships (R)&lt;/strong&gt;: Links connecting entities to semantic units.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  b. Graph Augmentation
&lt;/h4&gt;

&lt;p&gt;Next, graph algorithms identify &lt;strong&gt;key nodes and communities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attributes (A)&lt;/strong&gt; are extracted via LLM summarization of entities and relationships.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-level Elements (H)&lt;/strong&gt; are distilled summaries of community-level meaning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overviews (O)&lt;/strong&gt; serve as keyword-based titles for high-level elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This step also segments the graph into &lt;strong&gt;communities&lt;/strong&gt; using the &lt;strong&gt;Leiden algorithm&lt;/strong&gt; (Traag et al., 2019), preserving structural coherence.&lt;/p&gt;

&lt;h4&gt;
  
  
  c. Graph Enrichment
&lt;/h4&gt;

&lt;p&gt;Original text chunks are embedded to retain full context and improve relevance. Only a &lt;strong&gt;subset&lt;/strong&gt; is embedded to optimize for storage and efficiency.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Graph Searching
&lt;/h3&gt;

&lt;p&gt;When a query is made, NodeRAG performs a dual-layered retrieval process:&lt;/p&gt;

&lt;h4&gt;
  
  
  a. Dual Search
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Title-based exact match&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vector-based semantic match&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  b. Personalized PageRank (PPR)
&lt;/h4&gt;

&lt;p&gt;Starting from entry nodes, a &lt;strong&gt;shallow PPR algorithm&lt;/strong&gt; conducts a localized random walk to surface &lt;strong&gt;multi-hop reasoning paths&lt;/strong&gt;, without excessive noise.&lt;/p&gt;

&lt;h4&gt;
  
  
  c. Final Filtering
&lt;/h4&gt;

&lt;p&gt;Irrelevant or low-value nodes (e.g., keyword-only nodes) are excluded, ensuring a &lt;strong&gt;refined and targeted retrieval set&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Evaluation &amp;amp; Benchmarks
&lt;/h2&gt;

&lt;p&gt;NodeRAG has been benchmarked against NaiveRAG, GraphRAG, and LightRAG using datasets like &lt;strong&gt;HotpotQA&lt;/strong&gt;, &lt;strong&gt;MuSiQue&lt;/strong&gt;, and &lt;strong&gt;RAG-QA Arena&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspnwt8k5p4clejwga1yj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspnwt8k5p4clejwga1yj.png" alt="Part I Table shows evaluations of NaiveRAG, HyDE, LightRAG, GraphRAG, and NodeRAG on&amp;lt;br&amp;gt;
HotpotQA and MuSiQue (accuracy and average tokens).&amp;lt;br&amp;gt;
Part II Table shows the fraction of “wins" width="800" height="521"&gt;&lt;/a&gt;
when comparing one RAG method against another&lt;br&gt;
"/&amp;gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Results:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MuSiQue&lt;/strong&gt;: NodeRAG achieved &lt;strong&gt;46.29% accuracy&lt;/strong&gt;, outperforming GraphRAG (41.71%) and LightRAG (36.00%).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HotpotQA&lt;/strong&gt;: NodeRAG delivered comparable accuracy to GraphRAG (89.5% vs 89.0%) &lt;strong&gt;with 1.6k fewer retrieved tokens&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAG-QA Arena (Lifestyle domain)&lt;/strong&gt;: NodeRAG achieved a &lt;strong&gt;94.9% retrieval ratio&lt;/strong&gt;, compared to GraphRAG’s 86.3% and LightRAG’s 81.7%, with fewer tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These results highlight NodeRAG’s superior &lt;strong&gt;efficiency and accuracy&lt;/strong&gt;, especially in &lt;strong&gt;multi-hop&lt;/strong&gt; and &lt;strong&gt;summary-based QA&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Getting Started with NodeRAG
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🔧 Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Sample &lt;code&gt;.txt&lt;/code&gt;, &lt;code&gt;.md&lt;/code&gt;, or &lt;code&gt;.doc&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Anaconda or &lt;code&gt;uv&lt;/code&gt; for dependency management&lt;/li&gt;
&lt;li&gt;OpenAI API key (GPT-4o-mini recommended)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧪 Setup &amp;amp; Installation
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Clone the repository
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Terry-Xu-666/NodeRAG.git
&lt;span class="nb"&gt;cd &lt;/span&gt;NodeRAG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Create a virtual environment
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;With Conda:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;conda create &lt;span class="nt"&gt;-n&lt;/span&gt; NodeRAG &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10
conda activate NodeRAG
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With uv (faster):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;uv
uv &lt;span class="nb"&gt;sync
&lt;/span&gt;uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Prepare your files
&lt;/h4&gt;

&lt;p&gt;Create a project folder with an &lt;code&gt;input/&lt;/code&gt; directory. Add your documents there.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Configure NodeRAG
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; NodeRAG.build &lt;span class="nt"&gt;-f&lt;/span&gt; path/to/project_folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the &lt;code&gt;Node_config.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;model_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;model_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;
  &lt;span class="na"&gt;api_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;

&lt;span class="na"&gt;embedding_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Build the graph
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; NodeRAG.build &lt;span class="nt"&gt;-f&lt;/span&gt; path/to/project_folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78n8qg01je8eihlnlvic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78n8qg01je8eihlnlvic.png" alt="The first part of the process. Select y here." width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bs0fok3uw5rgl0x4xc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bs0fok3uw5rgl0x4xc4.png" alt="Process of building the graph has finished" width="584" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Run Queries
&lt;/h4&gt;

&lt;p&gt;Create a &lt;code&gt;main.py&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;NodeRAG&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NodeConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NodeSearch&lt;/span&gt;

&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NodeConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_main_folder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/path/to/project&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NodeSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Create a multiple choice question based on my resume.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 Visualizing the Graph
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6bajb0fq7myrrccimm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6bajb0fq7myrrccimm0.png" alt="Visualization of graph" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate an HTML graph with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; NodeRAG.Vis.html &lt;span class="nt"&gt;-f&lt;/span&gt; path/to/project_folder &lt;span class="nt"&gt;-n&lt;/span&gt; 600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will produce an &lt;code&gt;index.html&lt;/code&gt; file you can open in a browser to view a compact visual of your heterograph.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;NodeRAG brings a fresh, &lt;strong&gt;graph-driven perspective to RAG&lt;/strong&gt; by integrating semantic, structural, and contextual layers into a single heterograph. Its &lt;strong&gt;fine-grained decomposition&lt;/strong&gt;, &lt;strong&gt;explainability&lt;/strong&gt;, and &lt;strong&gt;retrieval efficiency&lt;/strong&gt; make it a compelling tool for anyone building advanced AI systems without enterprise-level infrastructure.&lt;/p&gt;

&lt;p&gt;Whether you're building a personal assistant, a document search engine, or an AI tutor, &lt;strong&gt;NodeRAG allows you to create a domain-aware, multi-hop capable retrieval engine—without breaking the bank&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Terry-Xu-666/NodeRAG" rel="noopener noreferrer"&gt;NodeRAG GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2504.11544" rel="noopener noreferrer"&gt;Original paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.bjorncode.dev/node-rag" rel="noopener noreferrer"&gt;Visual Example&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bjorncode.dev" rel="noopener noreferrer"&gt;My Portfolio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you have questions while setting it up, feel free to reach out—I’d love to help.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>llm</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
