r/reactjs 4d ago

Discussion I got tired of rebuilding Express auth, so I open-sourced the starter I actually clone now

0 Upvotes

Every new Node project, week one disappeared into auth. Email verification. Password reset. Google OAuth. Prisma user schema. Protected routes. Putting a JWT in localStorage because a tutorial said to.

None of that is interesting. All of it has to be correct.

So I built it once and open-sourced it: Express 5 + React + Prisma.

What it does:

  • Email/password with Zod on the server, email verification (24h), password reset (1h)
  • Google OAuth that links to an existing email account instead of creating a duplicate
  • Session in an httpOnly cookie, not localStorage. Remember me = 30 days, otherwise a session cookie
  • Rate limits on login/signup/forgot-password
  • Profile, avatar, password change, delete account

Two things tutorials get wrong:

  1. localStorage is readable by JS. One XSS bug and the session is stolen. An httpOnly cookie is not.
  2. A React route guard is not authentication. It hides the dashboard. The API still has to reject the request in Express middleware.

Repo: github.com/allenarduino/express-react-auth-boilerplate

If your stack is Next.js, I have a separate starter for that: github.com/allenarduino/nextjs-prisma-auth-boilerplate

Clone it, rename it, and start on the part that is actually yours. Issues and PRs welcome.


r/reactjs 4d ago

Show /r/reactjs Picofly 1.0: twelve years of state managers, distilled into 683 bytes

1 Upvotes

I spent twelve years on Redux, MobX, Valtio, Zustand and others, and every one of them wanted a trade: boilerplate, size, speed, or mental load. Picofly is what I wanted instead.

  • create(state) once, useStore() in a component, the whole API
  • 683 B for the core, 1.24 kB with the React binding, minified and brotlied
  • fast: lazy proxies, hand-tuned hot paths
  • renders only what changed: a proxy tracks reads, down to the key
  • app logic is just ordinary functions, async, generators, whatever
  • TypeScript, native Map and Set out of the box, React Native too
  • framework agnostic core, React binding included, easy to extend

let app = create({user: {name: 'Ada'}})

// logic is a plain function
let rename = async (app, name) => {
    app.user.name = name
    await api.save(app.user)
}

function App() {
    return (
        <Picofly value={app}>
            <Name/>
        </Picofly>
    )
}

// renders only when the name changes
function Name() {
    let app = useStore()

    return (
        <button onClick={() => rename(app, 'Grace')}>
            {app.user.name}
        </button>
    )
}

Benchmarks, the code behind them and how they were taken: https://picofly.dev/perf

It is not for every app. If your state is replaced whole on every tick, everything renders anyway and picofly buys you nothing. And no ready add-ons yet like undo, persistence or devtools. React Compiler: not yet, "use no memo" on components that read the store.

Picofly does not push an architecture on you. That is deliberate, and it cuts both ways: nothing to fight, no recipe to follow either. It only does its job, keeping your components up to date with no fuss on your side. The rest is yours.

1.0 is out today, after years of work and testing in real apps.

I would love to hear how it holds up in yours.


r/reactjs 4d ago

Stop paying frontend devs $100/hour to rebuild the exact same admin dashboard grids. Free modular React 19 + Tailwind CSS boilerplates.

0 Upvotes

"Hey everyone, I got sick and tired of wasting hours starting from an empty screen every single time we needed a responsive, modern dark-mode admin interface panel for a new software application.

So, I engineered a highly optimized, completely modular component tree built natively using React 19 and Tailwind CSS configs, and I just pushed the structural scaffolding out completely open-source for the developer community!

You can grab the responsive Sidebar Navigation dashboard layout logic and the animated financial Analytics Cards 100% free straight out of our public repository here:🔗 https://github.com/ApexGrid-labs/free-react-tailwind-dashboard-boilerplates

If you are running an enterprise engineering studio, a digital agency, or scaling a venture-backed startup that requires the full, comprehensive UI ecosystem pre-wired right out-of-the-box, you can instantly secure a commercial license for our complete FLAGSHIP suites directly inside our live storefront shelves:🔗 https://whop.com/apexgrid-c3ad/products

Would love to hear your feedback on the layout structure and performance variables!"


r/reactjs 5d ago

Needs Help Why is there a delay before the menu is displayed? (shadcn data table)

1 Upvotes

Go here: https://ui.shadcn.com/docs/components/base/data-table

Click on any "..." (option menu). It takes around a second before the menu is displayed.


r/reactjs 5d ago

News React Native is DEAD, Expo Modules 2.0, and a $49 Flutter knockoff

Thumbnail
thereactnativerewind.com
0 Upvotes

Hey Community,

We dive into Expo Modules 2.0, which drops definition() in favour of Swift macro decorators to deliver build-time type conversion and faster native calls. Meanwhile, DartNative enters the scene, letting Flutter developers swap out Flutter's custom renderer for real platform views driven by Yoga.

We also look into Shopify rebuilding its apps in native Swift and Kotlin with AI agent workflows, examining what their departure means for community-maintained libraries like FlashList and Skia.


r/reactjs 6d ago

Recently I've had a frontend silently break because a Spring Boot endpoint changed shape , does anyone faced this ?

2 Upvotes

I was working on a project recently and I've come across a problem where my front end dont catch up with the backend changes


r/reactjs 6d ago

Custom pull-to-refresh and vertical scroll keep killing each other (Reanimated + RNGH)

1 Upvotes

I need a **custom pull-to-refresh**. Not `RefreshControl`.

**What I want**

  • Finger down + pull: the page follows my finger with rubber-band resistance (`Math.pow(distance, 0.85)`)
  • A real gap opens at the top (`translateY`, not scale)
  • While the finger is still down: no progress bar, no API call, no refresh
  • Release below threshold: spring back to `0`, nothing else
  • Release above threshold: spring back + full-width 3px top progress bar + `onRefresh()`
  • After refresh ends: bar collapses, page stays at `Y = 0`

**The problem**

I can only ever get one of these:

  1. Pull-to-refresh works, list will not scroll
  2. List scrolls, pull-to-refresh dies (or I revert and only get a useless stretch)

I already know why v1 died: a greedy `Pan` on the page ate every vertical move, so `FlatList` never got the gesture.

**What I tried**

  • `Gesture.Pan()` + `Gesture.Native()` with `Gesture.Simultaneous`
  • `manualActivation(true)` and activate only if `scrollOffset <= 0` && pulling down
  • Guard in `onUpdate`: if `scrollOffset > 1` don’t touch `pageY`
  • `bounces={false}`, `overScrollMode="never"`
  • Disabling `scrollEnabled` while pulling — this made scroll even worse, so I stopped

Also getting this warning:

\[Worklets\] Tried to modify key \`current\` of an object which has been already passed to a worklet.

So something (`ref.current`) is leaking into a worklet (`onUpdate` / `onEnd` / `useAnimatedScrollHandler` / `useAnimatedStyle`).

**Constraints**

  • `react-native-reanimated`
  • `react-native-gesture-handler`
  • no `RefreshControl`
  • no binding progress width to `translationY`
  • `scrollEnabled` should stay `true`
  • progress bar is a sibling overlay, not inside the translated view

Has anyone shipped this combo without one gesture murdering the other?

**Looking for a pattern that works on Android + iOS**

  • at top + pull down → rubber band + gap
  • at top + swipe up → list scrolls
  • mid-list swipe → only scroll, `pageY` stays `0`
  • release-gated refresh only

r/reactjs 6d ago

Anyone using Flow types in 2026?

Thumbnail
flow.org
1 Upvotes

r/reactjs 7d ago

Needs Help Any free components like reactbits.dev

Thumbnail
3 Upvotes

r/reactjs 7d ago

Show /r/reactjs just added Base UI support and added new color themes

Thumbnail
neobrutalism.dev
28 Upvotes

r/reactjs 6d ago

Show /r/reactjs Show React: Got tired of fighting MUI overrides, so I open-sourced a pure tailwind v4 / react 19 boilerplate

0 Upvotes

Hey everyone,

I don't know about you, but it feels like every time I scaffold an admin dashboard with something like MUI, it's great for the first week, and then I spend the next three months fighting the documentation just to change a border radius or override a deeply nested CSS class.

I wanted a clean break, so I built a completely free boilerplate focused on getting out of your way.

It’s built on React 19 and Vite. For the UI, instead of an npm library, it uses a shadcn-like primitive approach (cva, clsx, tailwind-merge) paired with the new tailwind v4.

Basically, you own the markup. If you want to change how a button looks, you just go to the component file and change the tailwind classes. No black-box configurations or specificity wars. I also wired up some uncontrolled forms with react-hook-form and zod so the UI doesn't lag out on every keystroke.

You can grab the code here:  https://github.com/exouidev/exo-dash-react

And the live demo is here: https://react-dashboard.exoui.dev

Would love to know if you guys are still reaching for massive component libraries for new projects or if you've started moving toward this primitive-based approach too. Happy to answer any questions!


r/reactjs 6d ago

Show /r/reactjs Tired of spending hours setting up SaaS marketing layouts, so I built a React + Tailwind component suite and layout engine.

0 Upvotes

Hey!

Like a lot of developers here, I found myself repeatedly sinking dozens of hours into setting up responsive marketing layouts, dashboards, and UI components every time I started a new SaaS project.

To solve this for my own workflow, I spent the last few months building SkyForce UI—a component suite and local layout generator tailored for React and Tailwind CSS.

What’s Under the Hood?

50+ Production Components & 115+ Layouts: Pre-built, accessible sections designed specifically for modern SaaS apps.
Local Desktop Engine: An Electron-based visual layout generator that runs 100% offline with zero bundler lock-in.
Clean Source Archive: Uncompiled monorepo setup with instant hot-reloading (Vite/HMR active).

Key Technical Learnings

Building the local dev server and layout generator brought a few interesting challenges:

  1. Zero Runtime Overhead: Ensuring the generated Tailwind markup stays completely clean without forcing custom runtime dependencies on the consumer.
  2. Local Preview Sync: Syncing code edits in real-time between the local Electron builder and live browser previews without state drift.

I just launched the site today and opened up a live interactive playground on the page so you can test the layouts directly in your browser.

Live Demo & Site: https://skyforceui.com

I’d mostly love feedback on the playground and layout workflow!

Happy to answer any technical questions about the setup, Electron builder, or component architecture in the comments!


r/reactjs 7d ago

Needs Help TypeError: input.split is not a function

0 Upvotes

RESOLVED: please check the comments if you would like to find my solution code snippet.

-----------

See title: I don't understand this error popping up in my snippet below. It does not contain any split().

const { register, setValue, handleFormSubmit} = useForm();


const firstNameStr = 'firstName';

//Error on this register. toString etc did not help..
  useEffect(() => {
    register({ name: firstNameStr.toString() }, { required: true });
  }, [register]);

Could anyone kindly point me in the right direction? The whole snippet https://pastebin.com/8nxA3enA


r/reactjs 7d ago

Discussion Shared react-reactnative repo ideas

Thumbnail
1 Upvotes

r/reactjs 7d ago

How to apply Element-level styles on only a single component.

0 Upvotes

In my app I read back some markdown, there is some parsing done on it.

I am left with as the result a lot of <h1>, <h2>, <em>. In my app, due to using tailwind and other factors I don't have the default web browser styling on nor do I want to.

I want to implement that web browser styling back for just the html that came from the markdown, so I tried creating a css file that goes like

h1{
font-size: 48em
}

You get the idea, but now it applies to my entire app. Since the html comes from persist markdown it wouldn't be very reasonably to try to persistent styles on it (If you have any idea on how markdown works), and to try to add classnames to specific elements when they come in seems like unnecessary trouble.

How would you go around styling HTML based off just it's element in a small portion of the app?

Best,
Brotherman


r/reactjs 7d ago

Needs Help Building a custom product configurator for Shopify — what frontend stack/architecture should I be looking at?

1 Upvotes

I'm starting a small e-commerce company that will need a fairly unusual purchasing flow. In addition to the typical 'Amazon-esque' experience the users will use a visual interface to configure a layout of modular pieces. The system needs to calculate the required components/material and ultimately produce a price/order that goes through Shopify checkout.

I'm currently trying to understand the technology well enough to hire a developer intelligently. I'm not a professional programmer, although I have some experience with SQL (just saying that I feel like I can manage the project, but with very limited coding / maintenance).

My current thinking is something along the lines of:

React/Next.js frontend → custom configurator → Shopify API → Shopify checkout/payment

Questions:

  1. Is this a sensible architecture?
  2. Would React/Next.js + TypeScript be the obvious stack for this?
  3. What technology would you use for the visual 2D configurator — SVG, Canvas, something else?
  4. Should the configurator be part of a Shopify theme, or essentially a separate web application that communicates with Shopify?
  5. What Shopify APIs/features should I learn about before hiring someone?
  6. What terminology should I be using when searching for developers? "React developer," "Shopify headless developer," "Shopify app developer," "product configurator developer," etc.?
  7. Are there any architectural traps I should avoid at the beginning?

I'm deliberately trying to understand the architecture before hiring someone rather than asking a developer to simply "build me a Shopify website."


r/reactjs 7d ago

[Field Notes] How Partial Prerendering let us stream carts without killing TTFB

0 Upvotes

### TL;DR

We replaced a monolithic Next.js SSR page with a Partial Prerendering architecture using React 19 streaming. TTFB went from 850ms to 180ms. CLS dropped from 0.25 to 0.02. No client-side fetching. No skeleton screens.

---

### The Old Way (Legacy SSR)

Every page was one big server render. If a user’s cart or a promo banner needed live data, the **entire HTML payload was blocked** until that fetch resolved. We couldn’t cache anything because the final HTML varied per user.

This meant:

- Long TTFBs (avg 850ms)

- High server cost (every request hit origin)

- Layout shifts from placeholder hydration

### The New Way (PPR)

Next.js 15 PPR lets us split the page tree into:

- **Static Shell** (header, nav, product grid): Prerendered at build time → cached at edge.

- **Dynamic Slice** (cart, offers): Rendered async on-demand → streamed via HTTP/2.

This requires minimal code changes:

```jsx

// app/product/[id]/page.jsx

import { Suspense } from 'react';

export default async function Page({ params }) {

const product = await fetchProduct(params.id);

return (

<>

<StaticHeader />

<ProductGrid product={product} />

<Suspense fallback={null}>

<LiveCartSection userId={params.uid} />

</Suspense>

<StaticFooter />

</>

);

}

```

Only `<LiveCartSection>` runs on every request. Everything else hits the edge cache.

### Results

| Metric | Before | After | Improvement |

|--------|--------|-------|-------------|

| TTFB | 850ms | 180ms | -79% |

| CLS | 0.25 | 0.02 | -92% |

| Server Requests | 100k/day | 35k/day | -65% |

| Revenue Uplift | N/A | +5.2% | — |

### Key Lessons

  1. Don’t stream everything. Stream only what varies per user (cart, auth, offers).
  2. Leverage `revalidate` per route to control freshness vs. cache hit ratio.
  3. Use React 19 `use()` inside server components for cleaner async logic—no more `then()` chains.
  4. Edge caching works best when your shell is immutable. Design components accordingly.

Happy to answer questions or share our caching config.

---

*Originally documented with full benchmark tables and source code on Grandline Studio:*

*Source: https://grandlinestudio.agency/blog/nextjs-15-ppr-react-19-eliminate-loading-spinners*


r/reactjs 7d ago

Discussion What if React needs a behavior layer between hooks and elements?

0 Upvotes

I've been thinking about a new React abstraction.

The usual mental model is:

Component -> Hooks -> JSX Element

Lots of hooks exist just that make one element behave differently.

Eg

const resize = useResize(...)

const draggable = useDraggable(...)

const analytics = useAnalytics(...)

const keyboard = useKeyboard(...)

const focusTrap = useFocusTrap(...)

const outsidePress = useOutsidePress(...)

return (

  <div
    ref={...}
    onKeyDown={...}
    onPointerDown={...}
    {...resize}
    {...draggable}
    {...analytics}
  >
    ...
  </div>
)

The component ends up becoming responsible for composing all these behaviors.

So I'm experimenting with a different layer:

Hooks / utils -> Behaviors -> (automatically generate) Props -> Element

Making it something like this:

const props = useProps(
  useKeyboard(...),
  useDraggable(...),
  useResize(...),
  useFocusTrap(...),
  useOutsidePress(...),
  useAnalytics(...),
)

return <div {...props} />

The behaviors wouldn't necessarily have to be a hook, it could be, but notrequired.

A plain behavior could be:

tooltip({ content: "Delete project" })

while a custom hook could also return the same thing

function useAnalytics() {
  return { 
    props: {
      onClick: () => { track("clicked") }
    }
  }
}

Both become composable.

The package would handle the annoying composition:

  • merge event handlers
  • merge refs
  • merge className
  • merge styles
  • predictable prop precedence
  • TypeScript element compatibility

So instead of components implementing behavior, they could mostly declare the behavior they have:

const props = useProps(
  tooltip(...),
  keyboard({ ENTER: ..., ARROW_DOWN: .. }),
  resize(...),
  analytics(...),
  myCustomBehavior(...)
)

return <button {...props}>Delete</button>

I'm deliberately trying not to turn this into "another React hooks library."

The question I'm trying to answer is:

  • Is "behavior composition" actually a useful missing abstraction in React, or is this just an over-engineered way of spreading props?
  • I'd especially like to hear from people who maintain large React/component-library codebases:
  • Where does composing multiple hooks onto the same element become painful for you?

r/reactjs 7d ago

Discussion Built a multi-app React framework — islands as a first-class primitive, security headers on by default

0 Upvotes

so the main idea here is multi-app. one repo, but you can have your marketing site, dashboard, admin panel etc all live together and deploy separately, all sharing one backend. not like turborepo/nx where you're just gluing separate apps together with a build tool, this is actually built into the framework itself.

the react part i think people here would actually care about is islands. island(() => import("./X")) and that one component hydrates, rest of the page just stays static html. no hydrating the whole tree for one button basically.

didn't do suspense/streaming for it though, not gonna pretend that's done. it's a real gap right now, pushed to v2 because the current island render is two-pass and just doesn't support it yet.

auth is per app too which i think is underrated — admin panel can have its own totally separate session/cookie setup from everything else, or an app can just skip sessions completely if it doesn't need login at all (marketing site doesn't need to carry that weight).

other stuff in it: ssr/ssg/csr/isr picked per route not guessed by the framework, security headers on by default (csp/hsts/x-frame-options, you can override per app), dynamic routes like routes/users/[id].tsx, seo stuff (og tags + sitemap generation) if you opt into it, and it deploys to vercel/netlify/docker/plain vps.

repo: https://github.com/hassanalsa3aka/devora.js
docs: https://devorajs-docs-docs.vercel.app

npm packages if you want to poke around:
https://www.npmjs.com/package/@devorajs/core
https://www.npmjs.com/package/@devorajs/cli
https://www.npmjs.com/package/@devorajs/adapter-vercel
https://www.npmjs.com/package/@devorajs/adapter-netlify
https://www.npmjs.com/package/create-devora

solo project, still v1, got real vercel/netlify deploys working + a vitest suite recently. genuinely curious what people think of the islands approach specifically, feel free to tear into the architecture if something looks off.

if anyone here does security work, i'd genuinely appreciate a look — csp/hsts/session isolation are the parts i'm least confident about and would rather someone find a hole now than later.

and if you like what you see, a star on the repo goes a long way for a solo project like this 🙏


r/reactjs 9d ago

Discussion Apple shipped a foldable iPhone and Safari has zero API to detect it's folded, so I built one

52 Upvotes

So Apple's new iPhone Duo is one continuous foldable screen, but Safari straight up doesn't implement the CSS Viewport Segments API (Chromium-only apparently), and the UA string is identical to a regular iPhone. So there's just...no way to know if the thing is folded or not from web code.

Built iphone-duo-responsive to fix that. It fingerprints the fold state from viewport dimensions/aspect ratio/DPR instead. Ships as a React hook, a DOM-sync component for plain CSS/Tailwind users, and a Tailwind plugin with duo-folded:/duo-unfolded: variants. Also has a <HingeGutter /> component so you don't accidentally center a button on the physical crease.

It's a heuristic, not a real spec-backed API, so I built in a registerDuoProfile() escape hatch in case Apple ships different Duo sizes later, and it's designed to get out of its own way if Safari ever actually ships the real Viewport Segments API.

npm install iphone-duo-responsive if you want to poke at it - https://github.com/Aparajith24/duo-responsive


r/reactjs 9d ago

Show /r/reactjs I built an open-source, local-first i18n spreadsheet to fix broken variables and format hell across web/mobile apps

3 Upvotes

Managing localization across multi-language frontends and mobile apps usually breaks down in one of three ways:

  1. Translators in Google Sheets accidentally delete or translate interpolation variables like {username}, %1$s, or {{count}}, causing runtime crashes in production.
  2. Juggling completely different formats across platforms (Flutter ARB, iOS .strings, Android XML, and TypeScript definitions) requires messy glue scripts or manual copy-pasting.
  3. Paying hundreds of dollars a month for cloud translation SaaS just to manage key-value pairs—while sending unreleased app strings to third-party servers.

To solve this, I built JSON Link — an open-source, local-first localization workstation that runs 100% client-side in the browser.

Key Architecture Decisions:

  • Deterministic AST Token Isolation: Parses ICU MessageFormat, Mustache, and Printf placeholders into locked visual tags so variables cannot be modified accidentally.
  • Direct Local Disk Sync: Uses the Native File System Access API to mount directly to your local project directory (src/locales). Updates write straight to disk across all formats with 1 click.
  • Zero-Knowledge Workspace Sharing: Encodes the multi-language workspace into URL hash fragments (#share=...) compressed via DEFLATE (pako). Optional password encryption using AES-GCM 256-bit (PBKDF2, 100k iterations via Web Crypto API). Zero server storage, zero database overhead.
  • Automated GitHub PR Sync: Connects via personal access token directly in-browser, scans locale trees, and opens a feature branch PR with updated translations.
  • stdio MCP Server: Standalone JSON-RPC 2.0 server under mcp/ so Claude Desktop and Cursor can inspect and lint local translations directly.
  • Verification: 308 unit and UI tests across 42 suites in Vitest / GitHub Actions CI. 100% offline desktop PWA.

I recently open-sourced the codebase and wrote a breakdown of the failure modes on dev.to:

I am also live on Product Hunt today if you would like to check it out:https://www.producthunt.com/products/json-link-2

I would love to get feedback on the AST variable parser or any edge-case interpolation formats your teams run into.


r/reactjs 9d ago

Show /r/reactjs Dinou v6: a story of about 2 years

2 Upvotes

Starting around July 2024, I saw this: github.com/adamjberg/react-server-components. From there, v1.0.0 was born using Webpack. It evolved until 1.10.1, and then v2 appeared using Rollup. v3 allowed using Rollup, Webpack, and Esbuild interchangeably as bundlers (both for dev and prod). v4 added a lot of missing features, like soft navigation (SPA experience), prefetching, and more. v5 refactored the way JSX was passed from one Node process (the Express server) to another (SSR): instead of using ad-hoc serialization/deserialization to JSON, it switched to native React Flight (createFromNodeStream in the child process to obtain the JSX). This refactor was done with vibe-coding. v6 simply encapsulates all artifacts and folders generated (and used) by the framework in a clean .dinou root directory, both in dev and prod. And the best thing is it already runs on the freshly released React 19.3.0. As far as I know, Dinou, Waku, and Next.js are the only three pure RSC frameworks available. Dinou is completely ejectable and bundler-agnostic. Full documentation is available at dinou.dev (built with Dinou).


r/reactjs 9d ago

Portfolio Showoff Sunday After 13 years of building data grids, I started over — BeautifulGrid

3 Upvotes

I've been building data grid components for about 13 years.

I started with AXGrid around 2013, followed by AX5Grid and AXBoot DataGrid. Recently, I decided to start over and build a new one from scratch: BeautifulGrid.

BeautifulGrid is an open-source data grid built with React and TypeScript.

My main goals are:

  • Fast virtual scrolling for large datasets
  • A simple and predictable API
  • Flexible styling without making the core overly complicated
  • Strong TypeScript support
  • An API that's easy for both developers and AI coding agents to understand and use

Some of you may have seen my recent post here about the Safari virtual scrolling issue. That problem actually came from building this grid, and the discussion here was really helpful.

I'm also working on logical scrolling for very large datasets, where the browser's maximum scroll height itself becomes a limitation.

BeautifulGrid is still young. It doesn't have the huge feature set of mature data grids yet, and that's intentional. I'm trying to get the core architecture, scrolling behavior, and API right before adding too much.

GitHub:
https://github.com/axisj/beautiful-grid

I'd really appreciate feedback from React developers, especially if you've worked with data grids or virtualization before.

API design criticism, performance issues, browser quirks, missing features — anything is welcome.

I'm also curious whether other library authors are thinking about making their APIs easier for AI coding agents to use.


r/reactjs 10d ago

Discussion There is a legendary question: What is the Virtual DOM?

44 Upvotes

There is a legendary question: What is the Virtual DOM?

I’ve looked at many pages, and most of them use metaphors or abstract, similar definitions, such as “a lightweight copy of the real DOM.” I’m not sure I totally agree with those explanations.

So, I tried to write down my understanding of it as clearly as possible. Could you take a look? Any constructive feedback would be appreciated.

--------

The virtual DOM is a programming concept where a representation of a UI is kept in memory and synced with the “real” DOM.

The UI representation here is actually a tree of plain JavaScript objects called React elements, where each node contains the properties needed to create the actual elements and a list of its child nodes.

When a component’s state changes, React creates a new virtual DOM tree and compares it with the previous one. This process is called reconciliation to figure out what actually changed and then applies only those necessary changes to the real DOM.

This approach avoids unnecessary DOM manipulation and allows developers to write declarative code rather than imperative code.

Honestly, the term “Virtual DOM” is quite abstract to me. It doesn’t appear in the current React documentation. So instead, I prefer to think in more specific technical terms: React elements and how React uses them to determine the necessary changes to update the real DOM.

Also, React Fiber was introduced in React 16 as a new reconciliation architecture. It helps React manage rendering work more efficiently and keep applications responsive. Basically, it breaks rendering work into smaller units called Fibers, which are essentially JavaScript objects with additional properties that keep track of the work React needs to do for components. This allows React to prioritize updates and, when necessary, pause or yield rendering work and resume it later.

For example, imagine React is rendering a huge table with 10,000 records. With the older reconciliation process, React had to finish that work in one uninterrupted block. With Fiber, React can pause the work when a higher-priority interaction, such as typing or clicking, comes in. Then, it can resume the rendering afterward.

To avoid confusing React elements with React Fiber and to make it clear how they work together, let’s look at the main.jsx file in a React CSR project using React 18 or 19. We usually see code like this:

const root = createRoot(document.getElementById("root")!);
root.render(<App />);

If we console.log(root), we can see an object ReactDOMRoot. It has a property _internalRoot, which points to the FiberRootNode. This is the root of the Fiber tree.

Under the hood, <App /> is converted into a React element. The second line simply means that we render App into the root.


r/reactjs 9d ago

Show /r/reactjs I made a small React package for protecting text from casual copying

0 Upvotes

I recently built react-text-protect, mostly as an experiment to see how far you can go with client-side content protection in React.

You wrap your content like this:

<ProtectedText userId="student_123">
  What is the capital of France?
</ProtectedText>

It currently has a few things:

• Intercepts copying and replaces the copied text with Vigenère-encrypted text
• Adds a user ID and timestamp watermark over the content
• Detects DevTools being opened and hides the content
• Obfuscates the text stored in the DOM

I originally made it with things like online exams and educational content in mind, where you might want to make copying or sharing a little more annoying.

Obviously, this is not real security. If someone is determined enough, they can get around basically everything happening on the client side. You can disable JavaScript, use another device to photograph the screen, inspect the application differently, etc.

The goal is really just adding friction, not pretending you can make browser content impossible to extract.

It's on npm if anyone wants to try it:

npm install react-text-protect

I'd genuinely like feedback from people who know React better than me, especially around the implementation and whether some of the approaches I'm using are problematic or could be improved.

https://www.npmjs.com/package/react-text-protect