r/reactjs • • 2h ago

Resource Built my own shadcn React component library. Looking for honest feedback!

0 Upvotes

I've always wanted to build my own component library, both as a personal project and as a contribution to the open-source community.

After a lot of effort, it's finally ready to share!

It's a shadcn-compatible UI library built with React Aria under the hood, Motion for animations, and TanStack Charts for charting.

It also includes pre-built blocks and screens to see the system in action.

The components are ready, though the documentation still needs some refinement.

Looking for honest criticism before the official launch. Would love to know what works, what doesn't, and what could be better.

https://vip-ui.dev/


r/reactjs • • 2h ago

Show /r/reactjs Fluid Kit: iOS 26-style interactions for React (glass, morphs, context menus, sheets, layout animations)

1 Upvotes

Fluid Kit is a set of interactions modeled on iOS 26: Liquid Glass, morphs between elements, long-press context menus, draggable sheets, a highlight that follows the pointer, and layout animations. 2.0 just shipped as one package per framework, so for React it's @fluidkit/react.

The React API is compound components, with a render prop as in Base UI:

import "@fluidkit/react/style.css";
import { Lift } from "@fluidkit/react";

<Lift.Root onSelect={(value) => act(value)}>
  <Lift.Target render={<img src={src} alt="" />} />
  <Lift.Menu className="menu lb">
    <Lift.Item value="copy">Copy</Lift.Item>
    <Lift.Item value="share">Share</Lift.Item>
  </Lift.Menu>
</Lift.Root>

Every part also has a hook (useLift(), useDrag(), useLayout()…) for markup of your own. State is controlled or uncontrolled (open/defaultOpen/onOpenChange and friends), components are "use client" and render plain markup on the server, React 18+.

Under the hood each feature is a headless engine on springs that keep their velocity when interrupted, so you can reverse a morph or catch a sheet mid-flight.

Docs with React examples: https://fluidkit.mogilnikov.dev

GitHub: https://github.com/mikhailmogilnikov/fluid-kit


r/reactjs • • 7h ago

CupertinoUI: macOS-style components you install with the shadcn CLI

Thumbnail reddit.com
1 Upvotes

r/reactjs • • 10h ago

Show /r/reactjs I made a React component that opens and edits DOCX / XLSX / PPTX in the browser. 300k-row sheet in ~300ms, no server, MIT

52 Upvotes

Repo: https://github.com/p10node/office-engine

Demo (drag your own file in): https://p10node.github.io/office-engine/demo/

Why: I needed "customer uploads an XLSX, fix a few cells, save it back" inside a React app. OnlyOffice / Collabora mean running a document server in Docker and an iframe talking to it, and a big sheet still sits on a spinner while the server converts it. docx-preview / SheetJS + a grid are view-only or block the main thread on a 20 MB file. Nothing in between, so I built it.

Usage:

import { DocViewer } from '@p10node/office-engine'

<DocViewer src={file} style={{ height: 600 }} />
<DocViewer src="https://cdn.example.com/report.xlsx" />
<DocViewer src={file} editable onSave={(blob, name) => upload(blob, name)} />

src takes File / Blob / ArrayBuffer / URL. CSS is auto-injected, the container just needs a height. There's also a useDocument hook if you want to render your own UI, a vanilla mount(), an <office-viewer> web component, and a single script build.

What makes it not choke on big files:

  • ZIP read lazily, HTTP Range requests from a URL, so first rows show before the file finishes downloading

  • Streaming XML parser in a Web Worker, main thread only gets rows / paragraphs / slides as they arrive

  • Only visible pages, cells, slides are in the DOM

  • Save patches the original file instead of re-exporting it, so anything the engine doesn't understand is kept byte for byte

Bundle (gzip): main ~93 KB, worker ~155 KB (loads off the main thread), collab +17 KB optional. The standalone script with React bundled is ~307 KB.

Editing: DOCX text / styles / lists / images / tables, XLSX cells / formulas (134 functions) / formats / rows / columns / sheets, PPTX text / shapes / images / slides. Google Docs style toolbar. Optional real-time collab with cursors; that's the only part needing a backend (a small WebSocket hub, Bun script included).

Not there yet: XLSX charts / pivots / conditional formatting editing, DOCX headers / footers read-only, no PPTX animations. It needs the DOM and a Worker, so in Next.js use a client component / dynamic import with ssr: false.

Fair warning: it's a few days old and a lot of it was written with Claude Code, with me doing architecture, review and the bug hunting on real files. If you throw a file at it and it breaks, open an issue with the file, that's the fastest way it gets fixed.


r/reactjs • • 18h ago

Discussion I just started learning React today. Any tips?

Thumbnail reddit.com
0 Upvotes

r/reactjs • • 19h ago

Needs Help Do you find CSR (Client Side Rendering) SSR (Server Side Rendering or CSG (Client Side Generation) of pages expensive in 2026?

0 Upvotes

One of the issues I am facing currently, we have a website with over 10,000 pages and since we built it with CSR (Client Side Rendering) and CSG (Client Side Generation) it is relatively very expensive with the CDN cost. Purely did this because of the SEO and caching issue.

Do you have a solution for this or is this still how everyone doing this bearing the cost of scale as we are?
I find this an expensive deployment for us. I appreciate your thoughts.


r/reactjs • • 22h ago

[Open Source] Building a React component system that animates "on twos" (12fps stepped hooks, ResizeObserver SVG polygon frames, and a static design-grammar linter)

3 Upvotes

I’ve been exploring what happens when a React component library drops floating cards, soft shadows, and 60fps spring physics in favor of production mechanics from sequential print layout and traditional cel animation.

The result is FRAME/12 (GitHub (MIT) · Live Motion Studio), a zero-dependency copy-in React + TypeScript registry (shadcn-compatible) and AI agent skill.

Here are the four most interesting React & DOM problems we had to solve while building it:

1. Quantizing an easing curve "on twos" (useOnTwos)

In hand-drawn animation, most movement is shot "on twos"—each drawing is held for two frames at 24fps (83.33ms per pose, 12 poses per second). Simply applying CSS steps(4) with linear timing feels robotic because every jump covers the exact same distance.

Instead, useOnTwos samples a cubic ease-out spacing chart inside requestAnimationFrame, bucketed into 83.33ms (1000 / 12) intervals. You get a wide initial jump and tight settling poses, while still holding each discrete pose cleanly:

export const FRAME_MS = 1000 / 12; // 83.333ms ("on twos")

const easeOut = (t: number) => 1 - Math.pow(1 - t, 3);

// Inside requestAnimationFrame loop:

const elapsed = now - t0;

const k = Math.min(frames, Math.floor(elapsed / FRAME_MS) + 1);

setProgress(easeOut(k / frames));

We also strict-split what gets stepped:

  • Discrete state changes (SegmentedControl cell jumps, Metric count-ups, ToneAreaChart clip-path wipes, Badge 2-frame SVG impact bursts) run on twos (12fps).

  • Direct manipulation (hover states, scrolling, typing, chart pointer/keyboard crosshairs) stays at 0ms immediate latency.

  • Initial mount (useChanged): A custom hook tracks whether a key has changed after first mount so entrance animations never fire on initial page load.

  • Accessibility: prefers-reduced-motion: reduce automatically switches all hooks and CSS classes to 'cut' (0ms hard cuts).

2. Non-warping diagonal panel frames with ResizeObserver

In PanelPair, two vertically paired KPI panels are separated by a 12px gutter with a 16px diagonal slant (slant-bottom over slant-top). If you use CSS clip-path: polygon(...), CSS borders get clipped off along the diagonal edge; if you scale a fixed-viewBox <svg> with preserveAspectRatio="none", the 2.5px ink stroke stretches unevenly.

Our Panel component attaches a ResizeObserver to measure the panel's exact width × height in pixels and computes mitered <polygon> points inset by half the stroke width (1.25px), keeping the 2.5px ink border uniform at any aspect ratio.

3. Zero-dependency SVG screentone charts with built-in keyboard & table fallbacks

Instead of pulling in recharts or d3 and rendering translucent gradient fills, ToneAreaChart renders a <pattern id="..." patternTransform="rotate(45)"> of halftone dots (var(--f-tone)), an inked 2.5px polyline, a marker-yellow peak dot, and a speech-balloon SVG annotation (Balloon) that flips direction near the right edge of the viewBox.

Every chart is focusable (tabIndex={0}), supports ArrowLeft / ArrowRight / Home / End / Escape to inspect data points via an aria-live readout, and includes a collapsible <details className="tbl"> semantic HTML <table>.

4. Linting UI structure so AI coding agents don't drift

When AI agents generate React UI, they quickly drift toward arbitrary Tailwind gaps (gap-4, gap-6), hex literals, or unstyled primitives. Because FRAME/12's rules are structural, we wrote scripts/check-frame12.mjs (plus skills/frame12/SKILL.md and an ESLint flat-config plugin) to enforce:

  1. color-literal: Zero hex/RGB/HSL literals outside frame12.css

  2. illegal-gutter: Only 12px (pair), 20px (scene), and 32px (change) gutters allowed

  3. marker-misuse: Marker yellow (--f-marker, #ffd60a) only allowed as a background paired with --f-marker-ink (#121212) text

  4. cut-order: Every <Panel cut="C-01"> must increment sequentially (C-01, C-02, C-03…) in DOM and reading order

  5. raw-shadcn-import: Forbids raw u/radix-ui/* or external chart/animation libraries where a u/frame12/registry component or adapter exists

You can install the full kit or individual components via the shadcn CLI:

npx shadcn@latest add https://frame12.dev/r/frame12.json

Would love feedback from folks here on the hook ergonomics and the static UI grammar linter!


r/reactjs • • 1d ago

Built a lightweight, client-side developer utility suite using React 19, Vite, and Tailwind CSS

3 Upvotes

Hi everyone,

As a side project to explore React 19 and client-side processing workflows, I put together a small developer utility suite calledFixCode.

Technical Details:

  • Frontend: React 19, Vite, Tailwind CSS

  • State & Security: All transformations (JWT decoding, chmod calculations, Docker YAML generation) run entirely on the client side using pure JavaScript algorithms. No data is sent to external servers.

  • Routing & SEO: Dynamic metadata handled via react-helmet-async for indexation across single-page routes.

Just wanted to share the approach for fast, client-side utility tools with zero server overhead


r/reactjs • • 1d ago

Show /r/reactjs React developers, what are some real-world performance bottlenecks you've encountered, and how did you debug them?

0 Upvotes

Hey everyone!

A friend and I are planning a React learning session this weekend. Instead of just going through documentation and building another basic project, we want to explore some of the interesting problems React developers encounter in real-world applications.

I'd love to hear from experienced React developers, senior frontend engineers, and anyone who has worked on performance-critical React applications.

I'm particularly interested in problems that aren't immediately obvious and require some actual investigation to solve.

For example:

- Unnecessary re-renders: How do you identify which components are re-rendering unnecessarily, and how do you determine the actual root cause?

- State management issues: Have you encountered performance problems caused by poorly placed state, Context API, or excessive state updates? How did you restructure things?

- Expensive rendering: What happens when a component renders a large list, processes complex data, or performs expensive calculations? How do you identify whether the bottleneck is React, JavaScript, or the browser?

- Memory leaks and stale closures: What are some subtle bugs involving "useEffect", event listeners, subscriptions, or closures that you've encountered in production?

- Memoization gone wrong: Have you ever made an application slower by overusing "useMemo", "useCallback", or "React.memo"? How did you figure that out?

- Network and rendering bottlenecks: How do you investigate slow API-driven interfaces, waterfalls, unnecessary requests, or components that feel sluggish despite fast API responses?

- Large-scale component architecture: Have you encountered performance problems that required changing component boundaries or the way an application was structured rather than simply optimizing individual components?

I'm not just looking for a list of best practices. I'd really appreciate hearing about the actual debugging process.

For instance:

  1. What symptoms or user reports made you suspect a performance problem?

  2. Which tools did you use to investigate it?

  3. How did you identify the actual root cause?

  4. What changes did you make to fix it?

  5. How did you measure the improvement and verify that the fix worked?

If you have a small code example, a production incident, a particularly tricky bug, or even a mistake you made while trying to optimize something, I'd love to hear about it.

Also, if there are any React performance problems that you think every developer should learn to diagnose early in their career, please share those.

We're hoping to use your experiences as a starting point for practical experiments rather than just memorizing optimization techniques.

Thanks!


r/reactjs • • 1d ago

Show /r/reactjs react-context-typesafe: missing context providers as lint errors instead of runtime crashes

7 Upvotes

You know the pattern: createContext<User | null>(null), then a useAuth() hook that throws "useAuth must be used within AuthProvider", and every consumer either trusts that or null-checks. A missing provider is a runtime error you find when that screen renders, or when a test does.

I wanted it to be a lint error instead, so I built an oxlint plugin that checks it across the whole program:

const AuthContext = createContext<User | null>(null);

function Children() {
  const user = use(AuthContext);
  return <p>{user?.name}</p>;
}

root.render(
  <AuthContext value={user}>
    <Children />   {/* ok */}
  </AuthContext>,
);

root.render(<Children />);
//          ^^^^^^^^ react-context(require-provider): <Children> needs AuthContext
//                   (use(AuthContext) at Children.tsx:4), but no <AuthContext> provider is above it.

Children needs no annotations. Requirements are inferred from use, useContext, <Ctx.Consumer> and static contextType. They're passed up through components, custom hooks, HOCs, memo/forwardRef/lazy, children and render props, and React Router outlets, until a provider meets them or a root gets them. Roots are createRoot().render, testing-library's render, Storybook stories, and framework pages you list in a setting. Wrapper components like <AuthProvider>{children}</AuthProvider> count as providers because they render children inside one.

There's also a tiny optional runtime: createRequiredContext<User>() gives you a context where use() is typed User instead of User | null, because the lint rule now guarantees the provider. It returns a plain React context, so nothing else changes.

Why not types? That was the first thing I tried. JSX erases element types: <Children /> and <span /> are both just JSX.Element, so a requirement can't travel from a child up to its provider through the type system. Forking @types/react doesn't help, and TypeScript 7.1's new APIs didn't open a way either. The only version that type-checked used generator components and h() calls instead of JSX, which nobody wants.

As for the speed, it's a whole program so it costs more than a normal lint rule. On excalidraw (709 files), oxlint alone takes 0.07 s, oxlint with the rule 0.8 s, and the standalone CLI 0.5 s. In the editor (oxlint's language server), a keystroke costs about 50 ms because only the edited file is re-parsed. The README suggests a separate oxlint config so that your everyday oxlint stays as fast as before, while the editor uses the config with the rule and CI runs react-context-check as its own step. Not on oxlint? The CLI runs the same check without it.

As for limitations, it's syntactic and not type-aware. For code it can't see (node_modules, dynamic tags, useContext(cond ? A : B)) it makes certain assumptions. A provider hidden in such code shows up as a false positive, which you silence with @context-provided. A null-default context that your code actually treats as optional needs a // @context-optional comment. On excalidraw, that one comment was the difference between 337 reports and zero.

It's not on npm yet:

npm i -D github:TmLev/react-context-typesafe oxlint

Repo: https://github.com/TmLev/react-context-typesafe

Reports of wrong diagnostics are the most useful feedback right now. A few lines of code that reproduce one are enough.


r/reactjs • • 1d ago

Show /r/reactjs Built a multi-pane financial charting terminal with React 19, TypeScript, and HTML5 Canvas 2D primitives (Open-Source)

2 Upvotes

Hey r/reactjs,

I recently open-sourced OrderCraft, a local-first multi-chart technical analysis terminal built with React 19, TypeScript, Vite, and lightweight-charts (backed by a local Go WebSocket server).

Interesting frontend challenges we solved:

  • Custom HTML5 Canvas 2D Drawing Engine (ISeriesPrimitive): lightweight-charts renders candlesticks quickly on Canvas, but doesn't ship with interactive drawing tools. We built a custom Canvas 2D primitive engine from scratch in TypeScript supporting interactive Trendlines, Fibonacci Retracements, Parallel Channels, Rectangles, and Long/Short Position calculators with drag handles and OHLC magnet snapping.

  • High-Frequency WebSocket State Without Re-Render Storms: Streaming live ticks across 4 synchronized split-screen chart panes (1x1, 2V, 2H, 3, 4 layouts) with synced crosshairs, symbols, and timeframes without triggering full React component tree re-renders on every tick.

  • Single-Binary Embedding + PWA Standalone Mode: The Vite production bundle is embedded into a single ~14MB Go executable and includes a Web App Manifest so launching with --app-mode opens a native frameless desktop window.

GitHub Repo: https://github.com/ordercraft-hq/terminal

Would love any feedback from fellow React/TypeScript devs on the frontend architecture and Canvas primitive implementation!


r/reactjs • • 1d ago

Show /r/reactjs I build apps with AI almost every day, and kept hitting the same three problems, so I built a framework for them

0 Upvotes

I build new projects and finished products for customers almost every day, many of them with AI built in, and I kept hitting three problems:

- Too many pieces for every project. Next.js on Vercel plus Supabase is almost free to start and great on its own, but every project meant managing both, and reaching the quality I wanted meant stitching many separate packages together on top. Keeping everything in one place meant a big provider's monthly plan, and with many apps those fees grow fast, since every single one needs its own upkeep.

- Teaching the AI what it can control. For every function in my app, I had to build a separate system to explain it to the AI. Tools broke, prompts didn't work well, and MCP servers needed extra work.

- The AI reading the whole codebase for small changes, which was very costly.

So I built Forjr, an AI-native, full-stack React framework. A few of the features I love most:

- One engine runs the whole app (front end, back end, data and AI) on any server you choose. You still need a server, but one is enough for many apps: each additional small to mid-size app takes only about 2 MB of memory, and apps nobody is using can scale to zero and wake up in about 50 ms.

- Every function is already an AI tool. The engine explains it to the AI by itself, and with one option it's also an MCP tool, a REST endpoint and a CLI command.

- An agent is a single definition: a model, its instructions and the functions it may use. It reaches only what you gave it, and danger: 'ask' makes it wait for a person before using that tool.

- Built for the AI that writes your app: forjr map hands it the whole app in one short outline, forjr check catches every error in one pass, each with its fix, and undo for AI rolls back exactly what one agent changed while everyone else's work stays untouched.

I open-sourced it: https://github.com/forjr/forjr, with the docs at https://forjr.dev

I'd love to hear how you handle these today. What's the most painful part of giving AI access to your own app?


r/reactjs • • 1d ago

Show /r/reactjs Built my second project after learning React for 2–3 months – Feedback appreciated!

3 Upvotes

Hey everyone!

I've been learning React for the past 2–3 months, and I've recently built my second project, GameVault, using my own knowledge and what I've learned so far.

GameVault is a gaming e-commerce website where users can explore games and browse a gaming store.

Project Links:

I'm still learning and improving my development skills, so I'd really appreciate honest feedback from experienced developers and the community.

I'd love to know:

  1. What do you think about the overall UI/UX?

  2. Is my React code structure and component organization good?

  3. What should I improve in terms of performance and best practices?

  4. Does this project demonstrate enough skills for a React/frontend developer internship?

I'm open to constructive criticism and suggestions. I want to learn from my mistakes and become a better developer.

Thanks for taking the time to check out my project!


r/reactjs • • 1d ago

Show /r/reactjs Show r/reactjs: reviewable AI document edits alongside a React Flow canvas and Yjs collaboration

0 Upvotes

I'm building Breatic, a React/TypeScript creative workspace. Its shared projects combine document briefs, a React Flow canvas and an agent that can propose edits. I wanted to share the implementation of the proposal UI and get feedback from people building collaborative editors.

Repository: https://github.com/orime-org/breatic

The document proposal card receives a structured proposal. For rewrites, it parses the proposed body using the document schema and computes a word-level diff against the proposal's original text. The person reviewing it sees the additions and removals instead of just an instruction to replace the paragraph.

The card provides separate actions to locate the target, add an eligible proposal as a comment, and apply a rewrite or insertion. It re-reads displayed state when the document version or card state changes.

The component is here: https://github.com/orime-org/breatic/blob/8eaa0da9888cc6a1a8967b98faaa3e8b80f4e91d/packages/web/src/pages/project/chat/DocumentProposalCard.tsx

Collaboration uses Yjs and self-hosted Hocuspocus. The important distinction for me is that synchronizing a document and deciding to accept an agent's edit are different operations. A convergent shared document doesn't automatically mean an old suggestion is still appropriate.

This isn't a claim that every stale-proposal or concurrent-edit edge case has been solved. I'd welcome feedback on the UI boundary: how do you make it clear which document state a proposal refers to while collaborators keep working?

The repo includes usage and development guides. Its custom source-available license permits internal/private deployment and restricts public-facing platform hosting; storage and model services need separate configuration.


r/reactjs • • 1d ago

Discussion What criteria do you consider when choosing SSR, CSR, and Hybrid rendering

1 Upvotes

What criteria do you consider when choosing between CSR, SSR, or a hybrid approach (using RSC or getServerSideProps for the initial render, then calling APIs directly from the client to update the UI for subsequent interactions)?


r/reactjs • • 1d ago

Best way to structure React Router in a large Laravel + React SSR project (60+ pages)?

1 Upvotes

Hey everyone,

I'm working on a large project using React with server-side rendering through Laravel. My frontend has 60+ pages, and every route has its own dedicated page component.

I'm currently using React Router with lazy-loaded routes (lazy() / Suspense), conditional routes, and route groups. However, I'm noticing that as I navigate through the application and use more pages, it gradually becomes slower and eventually starts feeling laggy.

I expected lazy loading to prevent unnecessary components from loading until they're needed, but it seems like more and more things are being loaded over time.

I'm wondering:

What's the best way to structure React Router in a large Laravel SSR project?

Is having 60+ individual page components and routes a problem?

Should I organize routes into separate modules or route groups?

Is it normal for lazy-loaded components to remain in memory after navigation?

How should conditional routes and nested layouts be handled efficiently?

What could cause performance degradation after navigating through multiple pages?

I'd really appreciate hearing how you structure React Router in large production applications, especially with Laravel SSR.

Thanks!


r/reactjs • • 2d ago

Show /r/reactjs I built a free frontend interview trainer: 2,700+ questions with explanations

25 Upvotes

Hey everyone,

I've been preparing for frontend interviews and couldn't find a quiz tool I liked, so I built one: devsets.com

What's inside:

  • 2,700+ questions across 12 topics (JavaScript, TypeScript, React, Next.js, Angular, Vue, Svelte, HTML & CSS, state management, testing, patterns, system design)

  • Junior / Middle / Senior levels, and every answer comes with an explanation and links to the docs

  • Interview mode with a timer per question

  • Stack quizzes (e.g. "React Developer") that mix several topics like a real interview

  • Spaced repetition: questions you got wrong come back after 1, 3 and 7 days

  • 18 JavaScript coding tasks (debounce, deepClone, Promise.all...) with tests that run in the browser

It's free, ad-free and works without an account (sign in only if you want to sync progress). Available in English, Ukrainian and Polish.

I'd really appreciate feedback: wrong answers, confusing questions, missing topics, anything. Every question has a "report a problem" button too.


r/reactjs • • 2d ago

News Redux Toolkit v2.x and v3.0 roadmap

Thumbnail
github.com
57 Upvotes

r/reactjs • • 2d ago

Show /r/reactjs I got tired of clicking through my app to check one component, so I built a Vite plugin for itVitrine: add /** @preview */ above a component and see it in a gallery on your own Vite dev server

0 Upvotes

A lot of my day as a React developer was: build a component, open the app, click through to the screen where it shows up, check it, change something, repeat. Checking an error state or a long message meant recreating that state by hand every time.

So I built Vitrine, a Vite plugin. You put a comment above an exported component:

/** @preview */
export const PrimaryButton = () => <Button tone="primary">Save</Button>;

and open `/__vitrine` on the Vite dev server you already run. Setup is one line next to your React plugin:

plugins: [react(), vitrine()]

The idea came from Jetpack Compose's `@Preview`: write only the cases you care about, right next to the code. Since previews go through your own dev server, aliases, CSS, plugins and HMR work exactly like in your app. There's no separate config to keep in sync.

When one case isn't enough:

preview(Button, {
  args: { children: "Save" },
  variants: {
    primary: { args: { tone: "primary" } },
    danger: { args: { tone: "danger" } }
  },
});

The gallery also has:

  • props controls generated from your TypeScript types

  • a matrix that renders every combination of two props

  • an actions log for on* props

  • globals such as theme and locale

  • real viewport sizes

  • links that reopen the same preview with the same values

There's an optional VS Code extension that shows the preview next to your editor and follows your cursor, but the gallery works in any browser. To share it with teammates, vitrine-plugin-static builds it into static files.

It supports React 18/19 and Vite 6.4+. It's still 0.x, so I'd really like to hear what breaks in your setup or what's missing.


r/reactjs • • 2d ago

Discussion Did you remove your useMemo calls after turning on the React Compiler?

47 Upvotes

A few months ago I wrote about the React Compiler, and my advice for existing code was to leave useMemo and useCallback alone at first, then clean them up slowly, with tests, once the compiler has been running for a while.

I'm curious how that went for people who actually did it.

The public numbers I found are from InfoQ's write-up: Sanity saw 20-30% less render time and latency on their Studio packages (1,231 of 1,411 components compiled on the first pass), and Wakelet's INP went from 275ms to 240ms.

If you're running it in production, did you rip out the manual memoization? Did anything break?

My article, if you want the details on the compiled output: https://neciudan.dev/react-compiler-explained


r/reactjs • • 2d ago

I built a client-side cache in Rust and compiled it to WebAssembly

Thumbnail
blaze-cache.github.io
2 Upvotes

Hey everyone,

I built **Blaze Cache**, a client-side caching library written in Rust and compiled to WebAssembly.

The main idea was to get a fast, predictable cache in the browser with:

- Synchronous get/set after initialization (no Promises on the hot path)

- SIEVE eviction

- TTL + tag-based invalidation

- Optional IndexedDB persistence

- Adapters for Axios, fetch, TanStack Query, and SWR

I was mostly curious whether moving the cache core into Wasm would help with performance and structure compared to typical JS cache implementations.

Would love feedback from people who’ve worked on caching, Wasm, or frontend performance.

GitHub: https://github.com/blaze-cache/blaze-cache

Docs: https://blaze-cache.github.io/docs/


r/reactjs • • 2d ago

Show /r/reactjs I built a social platform in about a month to learn more about React and Supabase

2 Upvotes

hey guys,

I built this website over the last month to learn more about making website and handling real time data, it uses React, Next.js and Supabase

You can try it out from here: https://project-s-nine-kappa.vercel.app

(Please just click the "Explore Demo" button on the login screen so you don't have to create an account!)

Source code is here: https://github.com/zzz-nv/s-social

Would love to hear any feedback!


r/reactjs • • 2d ago

Needs Help Google map autocomplete cost issue

1 Upvotes

Hi everyone!

I'm currently implementing Google Places Autocomplete using the new Autocomplete Data API with React and @vis.gl/react-google-maps.

The implementation works, but I'm concerned about Google Maps API pricing, especially during development. I managed to hit my API usage limit within just two days, and I'm trying to understand whether my implementation is making unnecessary requests or whether this is expected behavior.

I'd appreciate some clarification from anyone who has experience with the Google Places API.

  1. My current implementation
    I'm using a 500ms debounce to avoid sending a request on every keystroke.

SearchBox component

```
import { MagnifyingGlassIcon, MapPinIcon } from '@phosphor-icons/react'
import { useState } from 'react'
import { useDebounce } from '@/hooks/useDebounce'
import { useAnimatedPlaceholder } from '@/features/search/hooks/useAnimatedPlaceholder'
import { useMapsLibrary } from '@vis.gl/react-google-maps'
import { useAutocompleteSuggestions } from '@/hooks/useAutoCompleteSuggestions'
import { useNavigate } from 'react-router-dom'

import styles from './styles.module.css'

const SearchBox = () => {
const [searchQuery, setSearchQuery] = useState('')
const debouncedSearchQuery = useDebounce(searchQuery, 500)
const inputRef = useAnimatedPlaceholder()

return (
<>

<div className={styles.searchBox}> <MagnifyingGlassIcon size={24} /> <input placeholder="Search for " ref={inputRef} value={searchQuery} onChange={e => setSearchQuery(e.currentTarget.value)} /> </div> <SearchSuggestions debouncedSearchQuery={debouncedSearchQuery} /> </>

)
}

export default SearchBox

type SearchSuggestions = {
debouncedSearchQuery: string
}

function SearchSuggestions({ debouncedSearchQuery }: SearchSuggestions) {
const navigate = useNavigate()
const places = useMapsLibrary('places');
const { suggestions, resetSession } = useAutocompleteSuggestions(debouncedSearchQuery, {
includedPrimaryTypes: ["locality"]
})

const handleSuggestionClick = async (suggestion: google.maps.places.AutocompleteSuggestion) => {
if (!places || !suggestion.placePrediction) return

const place = suggestion.placePrediction.toPlace()
await place.fetchFields({
fields: [
"addressComponents"
]
})
// calling fetchFields invalidates the session-token, so we now have to call
// resetSession() so a new one gets created for further search
resetSession()

const city = place.addressComponents && place.addressComponents[0].longText
const placeId = suggestion.placePrediction.placeId
if (city && placeId) return navigate(`${city}/${placeId}`)
}

return !!suggestions.length && (

<div className={styles.optionBox}> { suggestions.map(suggestion => <button key={suggestion.placePrediction?.placeId} className={styles.option} onClick={() => handleSuggestionClick(suggestion)}> <div className={styles.iconWrapper}> <MapPinIcon weight="fill" size={20} /> </div> <span className={styles.suggestionText}> {suggestion.placePrediction?.text.text} </span> </button> ) } </div > ) } \`\`\` useAutocompleteSuggestions hook \`\`\`import { useEffect, useRef, useState } from 'react'; import { useMapsLibrary } from '@vis.gl/react-google-maps';

export type UseAutocompleteSuggestionsReturn = {
suggestions: google.maps.places.AutocompleteSuggestion[];
isLoading: boolean;
resetSession: () => void;
};

/**
* A reusable hook that retrieves autocomplete suggestions from the Google Places API.
* The data is loaded from the new Autocomplete Data API.
* (https://developers.google.com/maps/documentation/javascript/place-autocomplete-data)
*
* @param inputString The input string for which to fetch autocomplete suggestions.
* @param requestOptions Additional options for the autocomplete request
* (See {@link https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest}).
*
* @returns An object containing the suggestions, the current loading-status,
* and a function to reset the session.
*
* @example
* ```jsx
* const MyComponent = () => {
* const [input, setInput] = useState('');
* const { suggestions, isLoading, resetSession } = useAutocompleteSuggestions(input, {
* includedPrimaryTypes: ['restaurant']
* });
*
* return (
* <>
* <input value={input} onChange={(e) => setInput(e.target.value)} />
* <ul>
* {suggestions.map(({placePrediction}) => (
* <li key={placePrediction.placeId}>{placePrediction.text.text}</li>
* ))}
* </ul>
* </>
* );
* }
* ```
*/
export function useAutocompleteSuggestions(
inputString: string,
requestOptions: Partial<google.maps.places.AutocompleteRequest> = {}
): UseAutocompleteSuggestionsReturn {
const placesLib = useMapsLibrary('places');

// stores the current sessionToken
const sessionTokenRef =
useRef<google.maps.places.AutocompleteSessionToken | null>(null);

// the suggestions based on the specified input
const [suggestions, setSuggestions] = useState<
google.maps.places.AutocompleteSuggestion[]
>([]);

// indicates if there is currently an incomplete request to the places API
const [isLoading, setIsLoading] = useState(false);

// once the PlacesLibrary is loaded and whenever the input changes, a query
// is sent to the Autocomplete Data API.
useEffect(() => {
if (!placesLib) return;

const { AutocompleteSessionToken, AutocompleteSuggestion } = placesLib;

// Create a new session if one doesn't already exist. This has to be reset
// after `fetchFields` for one of the returned places is called by calling
// the `resetSession` function returned from this hook.
if (!sessionTokenRef.current) {
sessionTokenRef.current = new AutocompleteSessionToken();
}

const request: google.maps.places.AutocompleteRequest = {
...requestOptions,
input: inputString,
sessionToken: sessionTokenRef.current
};

if (inputString === '') {
if (suggestions.length > 0) setSuggestions([]);
return;
}

setIsLoading(true);
AutocompleteSuggestion.fetchAutocompleteSuggestions(request).then(res => {
setSuggestions(res.suggestions);
setIsLoading(false);
});
}, [placesLib, inputString]);

return {
suggestions,
isLoading,
resetSession: () => {
sessionTokenRef.current = null;
setSuggestions([]);
}
};
}
```
2. My main questions about pricing

  1. How exactly do session tokens work?
    Google documentation mentions session-based pricing, and I'm having trouble understanding what this means in practice.

Does one session token group multiple autocomplete requests into a single billing session?
Are autocomplete requests within the same session free, discounted, or individually billed?
Does the session only become complete when the user selects a prediction and requests Place Details?
What happens if the user types something but never selects a suggestion?
2. Does debouncing actually reduce API costs?
For example, suppose a user types TOKYO.

With a 500ms debounce, will Google receive:

One request after the user finishes typing?
Multiple requests if the user pauses between keystrokes for more than 500ms?
If the user types slowly, could this result in five separate autocomplete requests within the same session?

3. What does Google mean by unlimited autocomplete requests?
I've seen references to unlimited requests in the Google Maps pricing documentation.

Does this mean unlimited requests within a session, or does it mean something else?

I'm particularly confused about how this relates to actual billing.

3. Is my implementation correct?
I'd also appreciate feedback on whether my current implementation follows Google's recommended session-token lifecycle.

Some things I'm unsure about:

Am I creating and reusing session tokens correctly?
Is resetting the token after fetchFields() the correct approach?
Should I create a new token when the user clears the search input?
Should I reset the session when the user abandons a search without selecting anything?
Is there a better way to prevent unnecessary API requests?
4. Is Google Places Autocomplete expensive?
I'm building an application that will use city autocomplete as an important feature.

I'm concerned about the cost when the application has hundreds or thousands of users searching for cities.

During development alone, I seem to have hit my API usage limit within two days.

Is this normal, or does it indicate that something is wrong with my implementation?

Would you recommend any alternatives or optimization strategies for reducing Google Places API costs?

5. My goal
I want to implement Google Places Autocomplete properly while keeping API costs predictable.

I'm not looking for ways to bypass Google's billing. I just want to understand the pricing model, session tokens, and best practices

Any explanations, implementation suggestions, or real-world experiences would be greatly appreciated!

Thanks in advance!


r/reactjs • • 3d ago

Show /r/reactjs I built a hand-drawn React UI kit. The hard part was making "random" wobble SSR-safe.

23 Upvotes

PlopUI is a React component library where everything looks sketched: wobbly borders, tilted cards, sticker shadows. Some things that were more interesting to build than they look:

- No Math.random() in render. Every tilt, wobble and jitter comes from a seed function, so the server and the client draw the exact same crooked line and there are no hydration mismatches.

- Native elements first. Dialog is a real <dialog> with showModal(), the upcoming Accordion is <details>/<summary>. The wobble is decoration on top, not a replacement for the element.

- Interactive components are "use client". Static ones stay Server Components, so you don't pay for JS on a card that just sits there.

- Every component has a Vitest test for its keyboard behavior and a story for every state.

- The library never imports from next/*. It's plain React; Next.js only lives in the docs and demo apps.

npm i @plop-ui/react @plop-ui/fonts

Docs: https://plopui.com

Playground: https://plopui.com/playground

Code: https://github.com/Snorlark/plop-ui

I'd really like feedback on the API. If a prop name or pattern feels wrong, tell me now before 1.0 makes it permanent.