Skip to content

JoeS51/React-lite

Repository files navigation

React Lite

A lightweight reimplementation of React's core ideas with a virtual DOM, a custom renderer, JSX createElement, reconciliation, and hooks.

Built from scratch to understand how React works internally and to explore tradeoffs in my own implementation.

Features

  • Virtual DOM nodes with tags, props, and children
  • Text node handling via createTextElement
  • Functional components with props and children
  • Reconciliation for create, delete, tag swap, and update
  • Keyed list reconciliation support
  • DOM prop updates with attribute diffs
  • Hooks with per render call order indexing
  • Effects and cleanup with dependency tracking

Hooks Supported

  • useState
  • useEffect
  • useRef
  • useMemo
  • useCallback
  • useReducer
  • useLayoutEffect

API

Export Description
createElement JSX factory for virtual DOM nodes.
render Render a virtual node into a container.
setRootComponent Set root component and trigger rerender.
useState Local state with rerender on update.
useEffect Effect after paint with optional cleanup.
useRef Stable ref object with current.
useMemo Memoized computed value.
useCallback Memoized function reference.
useReducer State with reducer dispatch.
useLayoutEffect Effect after DOM update before paint.

How to Run

  1. Start a local server in the repo root:
python3 -m http.server 8000
  1. Open http://localhost:8000 and load index.html or use a sample.

  2. Import in your JSX file:

import ReactLite, { useState, useEffect, useRef, setRootComponent } from './ReactLite.js';
  1. Mount your app:
setRootComponent(App, document.querySelector('#root'));

Project Structure

  • ReactLite.js is the core implementation.
  • concept-examples/ contains standalone hook and reconciliation demos.
  • article-checkpoints/ mirrors the tutorial progression with runnable examples.

For article-checkpoints, open any index.html file directly in a browser. The JSX is compiled in the browser via Babel.

Core Design Choices

Virtual DOM Representation Each virtual node is an object with tags, props, and children. Text nodes use createTextElement so reconciliation can treat every node the same way.

Functional Components If createElement receives a function tag, it calls that function with props and children and returns its output.

Reconciliation Algorithm The reconciler handles new nodes, deletions, tag changes, and updates for matching tags. It stores a reference to the real DOM node at reactElement.dom to avoid real DOM traversal.

Hooks via Global State Hooks use arrays indexed by call order, which is why hooks must be called consistently each render. Indices reset at the start of a render cycle.

Effect Cleanup Effects can return cleanup functions. Cleanup runs before the next effect with changed deps and on unmount paths.

What's Next

  • Component unmount lifecycle improvements
  • Better error handling and dev diagnostics

Limitations

This is a learning focused implementation, so several core React features are not included:

  • No Fiber architecture or concurrent rendering
  • No class components or lifecycle methods (will add this eventually)
  • No server rendering or hydration
  • etc (many more I'm missing)

About

A reimplementation of React from scratch

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors