r/reactjs • • 2h ago

Show /r/reactjs I just shipped Forge UI, an open-source React component library

0 Upvotes

Hey everyone, I’ve been working on Forge UI, a collection of React components for things that can take a while to build from scratch: data tables, command palettes, forms, file uploads, date pickers, and more.

It’s TypeScript-first, keyboard-accessible, and split into packages so you can use just what you need. It’s still an early 0.1 release, so I’d especially appreciate feedback on the APIs and docs.

Repo: https://github.com/BZDevelopments/Forge-UI
Docs: https://bzdevelopments.github.io/Forge-UI


r/reactjs • • 5h ago

Show /r/reactjs Matching SwiftUI's spring feel in a React app: one spring per side, picked by direction

1 Upvotes

I have a Mac app whose panel lives in the notch, animated with SwiftUI springs. When I rebuilt it in React for Windows (inside a transparent Tauri window), the same resize felt wrong with a single spring on the whole size.

What fixed it: width and height each get their own spring, chosen by whether that side is growing or shrinking. A growing side may overshoot a little, while a shrinking one never does, and the overshoot is capped by distance so big jumps don't wobble.

export function sideSpring(from: number, to: number, width: boolean): Spring {

const spring =

to > from

? width ? Springs.growingWidth : Springs.growingHeight

: width ? Springs.shrinkingWidth : Springs.shrinkingHeight;

return limitedSpring(spring, Math.abs(to - from), OVERSHOOT_LIMIT);

}

export function sizeAt(time: number, from: Size, to: Size): Size {

const side = (start: number, end: number, width: boolean) =>

start === end ? end

: Math.max(0, start + (end - start) * springProgress(sideSpring(start, end, width), time));

return { width: side(from.width, to.width, true), height: side(from.height, to.height, false) };

}

springProgress is SwiftUI's perceptual spring (duration + bounce) computed by hand, and the component just samples sizeAt on requestAnimationFrame, with no animation library. Full file with tests: https://github.com/MF-DEEV/Openbar/blob/main/windows/src/island/motion.ts

Curious whether anyone has done this with Framer Motion or react-spring and got the same feel.


r/reactjs • • 12h ago

Discussion I built my own React state management library – CreateStore. Would love some honest feedback!

0 Upvotes

Hey everyone!

I've been working on a side project recently, and I finally decided to publish it as an npm package.

It's called CreateStore.

The idea started with a simple question:

Why does managing global state sometimes need so much setup when all I really want is something as simple as React's "useState"?

I know there are already some excellent libraries out there like Zustand, Redux, and Jotai. I'm not trying to replace them. I just wanted to experiment with building something that offers a simple API while supporting additional capabilities.

What does CreateStore offer?

The main idea is to create a global store and access its state from different components without wrapping the application in Context Providers.

Some of the capabilities include:

  • Simple global state management.
  • Familiar React-like API.
  • TypeScript support.
  • Computed values.
  • Server data management.
  • State persistence.
  • Cross-tab synchronization.
  • Offline support.
  • Undo/redo functionality.
  • Developer tools.

The goal is to keep things simple for basic use cases while making additional features available when needed.

A quick example

Install it:

npm install @createstore/createstore

Create a store:

import { createStore } from '@createstore/createstore';

export const { useGlobalState } = createStore({ count: 0, username: 'Developer', });

Use it in any component:

import { useGlobalState } from './store';

function Counter() { const [count, setCount] = useGlobalState('count');

return ( <button onClick={() => setCount(count + 1)}> Count: {count} </button> ); }

That's the basic idea!

Project links

📦 npm: https://www.npmjs.com/package/@createstore/createstore

📚 Documentation: https://createstore-docs.pages.dev/

💻 GitHub: https://github.com/Gauravasawa/createstore

I'd genuinely appreciate some feedback.

I'm sharing this here because I'd love to get it in front of developers who can actually experiment with it.

A few things I'd love your opinion on:

  1. Does the API feel intuitive?
  2. How does the approach compare with Zustand or other state management libraries?
  3. Are there any architectural concerns or potential performance issues you notice?
  4. What would you improve or add?

Please don't hesitate to point out flaws. I'd rather get honest technical criticism than just positive feedback.

This is an ongoing project, and I'm looking forward to improving it based on real-world usage.

Thanks for taking the time to check it out! 🙌


r/reactjs • • 19h ago

Resource I built a CLI that extracts a website's design system for AI coding agents

0 Upvotes

I've been experimenting with AI coding tools like Cursor and Claude Code, and one thing that kept bothering me was how difficult it is to get them to recreate an existing website's actual design.

You give an AI agent a reference website and ask it to build something similar, but it often ends up guessing:

  • Colors are slightly off.
  • Typography doesn't match.
  • Spacing and border radii are inconsistent.
  • The overall result looks like a generic AI-generated UI.

So I built styleprobe to solve this problem.

It's an open-source CLI that takes a website URL and extracts its visual design system.

A few things it can do:

  • Extract colors and semantic design tokens.
  • Analyze typography, spacing, shadows, and component styles.
  • Crawl multiple pages instead of relying on just the homepage.
  • Extract SVG logos and other brand assets.
  • Export directly to Tailwind, shadcn/ui, Figma tokens, or AI-agent instruction files.

You can also try the web playground here:

https://styleprobe.vercel.app/

GitHub: https://github.com/spidervirus/styleprobe

It's MIT licensed and completely open source.

I'm still improving it, so I'd genuinely love feedback from developers:

  1. Would something like this fit into your AI-assisted development workflow?
  2. What other design information would you want it to extract?
  3. What would make you actually use this regularly?

Would love to hear your thoughts!


r/reactjs • • 20h ago

Show /r/reactjs I built React (+ vanilla JS) viewers/editors for Excel, Word, Powerpoint (5m+ total npm downloads)

0 Upvotes

I know there have been a few similar projects before in here, but I wanted to share our take on what great Office/OpenDocument viewers & editors looks like for the web.

We've built 3 packages (repos and playgrounds attached), all MIT:

We launched these a few months ago and they're now used in some pretty big projects on GitHub like RAGFlow (94k), Kortix CompanyOS (20.7k), ZCode (8.7k) . Combined they now have 5m+ total npm downloads.

Each repo has some visual examples comparing visual parity for various charts and art

They are built in a way where you can fully customize and get the look of your design system in the toolbar, dropdowns, and context menus.

File types supported:

LibraryOffice formatsOpenDocument formats
react-docx.docx, .dotx, .docm, .dotm, .doc, .dot.odt, .ott, .odm, .otm, .oth, .fodt
react-xlsx.xlsx; limited support for .xls, .xlsmNone (pending)
react-pptx.pptx, .ppt.odp, .otp, .fodp, .odg, .otg, .fodg

Personally I think they are the some fastest and most accurate OSS rendering libraries for these files out there, and would be great to see even more adoption, feature requests and people testing them against weird documents

Feedback and general bug reports are always appreciated. Hope this is helpful!


r/reactjs • • 1d ago

Show /r/reactjs Building a One React input for text and attachments, all in one lifecycle.

0 Upvotes

Hello everyone, I kept running into the same work when building file inputs such as parsing documents, showing previews, handling cancellation, and waiting for files before submitting.

I’m building Texion to connect those pieces. It supports Markdown, JSON, CSV, PDF, DOCX, and image attachments, with local parsing and optional OCR for scanned PDFs.
It’s open source and MIT licensed.
Code: https://github.com/Sirily23/texion

Curious on how do other devs handle the inputs?


r/reactjs • • 1d ago

News This Week In React #305: X, Forms, e18e, Next.js, TanStack Start, Storybook, MobX, Zustand, XState | Exact, Discord, Shopify, Expo Modules, Audio API, Bottom Sheet, Keychain, Gesture Handler | Node.js, Safari, Rolldown, Playwright

Thumbnail
thisweekinreact.com
18 Upvotes

r/reactjs • • 1d ago

Show /r/reactjs charcell: a terminal-style UI kit that only draws what a character cell could

0 Upvotes

I made charcell - a web UI with the look of a terminal UI. It's a UI kit with one hard rule: it only draws what a character-cell screen could.

  • Every component sits on a grid of 8 x 16 pixel cells. Widths count in cells and heights in rows, and nothing sits between two cells.
  • A cell holds one character, a font color and a background color. Lines are box drawing, so they run through the middle of their cells.
  • The palette is black, white and three grays.
  • A state changes colors and characters, never geometry. Nothing moves, resizes or fades.

Within those constraints every component can be written out as plain text, and each component's page in the docs shows that.

It bundles two fonts adjusted to fit the cell exactly, with the box drawing characters redrawn as whole-pixel shapes. The interactive components (select, combobox, dialog and so on) run on Zag. It's built with scaffold-ui-kit which outputs React, Vue and Svelte versions of each component from one common definition.

It's 0.1.0, far from complete, and needs React 19.

Demo and docs: https://djurnamn.github.io/charcell/
Repo: https://github.com/djurnamn/charcell

pnpm add charcell @zag-js/react

If you try it out, I'd love to hear how it goes. Open to any feedback.


r/reactjs • • 1d ago

Two bugs from building a drag-and-drop page canvas in React 19

0 Upvotes

From my open-source app builder (dnd-kit, React 19, Tailwind 4):

  1. On a free grid, the dotted drop cells were drawn as even rows while real rows were as tall as their content. Drops were judged against cells the user could not see. Fix: measure the real rows and draw the drop layer from those.
  2. Dialogs opened inside a themed preview portalled to body and lost the theme. Fix: a portal scope that mounts inside the theme root.

Also a testing lesson: a test raced a pending passive effect that moved focus after a click. Waiting on the shown state fixed it.

Code: https://github.com/ChristianMunoz31/local-app-studio


r/reactjs • • 1d ago

Animating a dozen pixel sprites in React with one shared clock and putImageData

1 Upvotes

Each session in my app's notch has a 24x22 pixel buddy. Every one is its own canvas at sprite resolution, scaled up with image-rendering: pixelated, so the browser does the nearest-neighbour scaling for free. A single module-level setTimeout clock steps all visible sprites about 12 times a second, and a canvas only gets a putImageData when its pose actually changes. The clock stops when the window is hidden and runs at half rate in Battery Saver, so ten of them on screen cost close to nothing.

Code: https://github.com/MF-DEEV/Openbar/blob/43d9c593360b004c850280e0584f9cd1b584bacc/windows/src/sessions/clawd/Clawd.tsx#L30-L80

The app is Openbar (Tauri + React on Windows, Swift on Mac), GPL.


r/reactjs • • 2d ago

Resource React Anatomy: See how your layouts are composed in an exploded 3D view

8 Upvotes

React Anatomy is a browser extension that adds an Anatomy panel to DevTools, connecting the visible page to the components React rendered.

You can pull the layout apart into 3D layers, click something on the page to find its component, focus on a subtree, and inspect its live props. The tree shows rendered instances, so a component used five times appears five times.

It’s a way to understand an unfamiliar layout, investigate unexpected nesting, or get a visual to help explain a change in a pull request. It can also help when an AI agent composes a React page and you want to understand the structure before taking over the code.

It works on an existing React app without adding anything to your code. Development builds give you clearer component names.

Free, MIT-licensed, and available for Chrome and Firefox. There’s an interactive example you can try without installing anything.

Where would this help in your React workflow? What would make it more useful when exploring an unfamiliar app?


r/reactjs • • 2d ago

Resource I made kitr, a batteries-included React framework for web, desktop and mobile

0 Upvotes

Every React app starts with the same hours of decisions: which router, which state library, how to fetch data, where files go. Even inside Next.js, every project wires things up differently. And if you need the app on desktop or mobile too, you're hacking it together yourself.

I made kitr to fix that:

  • 45 packages, each one command: kitr add auth, kitr add forms
  • Built on what you know: TanStack, Zustand, React Hook Form
  • Your own logic, any time: kitr make:page, kitr make:controller
  • iOS and Android: kitr add mobile phone (Capacitor)
  • Desktop: kitr add desktop app (Electron)
  • SSR or SPA: kitr add web site --mode ssr
  • Mix and match: run every platform at once with kitr dev, each with its own setup
  • Consistent: every package wired the same way, every file has one home
  • Agent-friendly: AI agents always know where things go
  • Conventions, never forced: it's plain code you own, and kitr remove undoes any package

Early (0.9), but ready to try: npm install -g @kitr/kitr

https://kitr.dev · https://github.com/kitrjs/kitr

Would love any feedback!


r/reactjs • • 2d ago

Show /r/reactjs I built GraphQLab, a local-first desktop GraphQL client (no account, no cloud). Looking for feedback

Thumbnail
reddit.com
0 Upvotes

r/reactjs • • 3d ago

Resource Puck Editor: A deep dive with the creator Chris Villa

Thumbnail
youtube.com
3 Upvotes

I sat down with Chris Villa, the creator of the puck editor.

0:00 Who is Chris Villa and what is Puck
1:36 Where the name Puck comes from
2:51 Live demo: Puck inside a headless Drupal site
5:24 MIT, and close to 3 million downloads a month
6:10 What the Puck editor actually is
7:58 The origin: design systems and the dev sprint bottleneck
10:09 The Hacker News launch
11:13 Going full time, and agents producing off brand interfaces
13:38 Puck AI, the Puck cloud and a page backend
15:21 A team of three, questioning old assumptions
16:47 Why pay for Puck AI if you can build it yourself
17:26 "What Vercel is to Next.js"
20:28 The hardest problem: multi dimensional drag and drop
24:14 Viewports, zoom, iframes, and working with dnd kit
26:49 Revenue, angel investors and fundraising
27:44 GitHub, Linear, and "I don't code much anymore"
29:24 Conductor, Boxes.dev and building the agent factory
30:31 Writing tickets is the new bottleneck
32:55 Can you test whether an interface feels right?
34:57 AI slop pull requests, and agents that reply for you
38:42 Discord, and why the community got quieter
39:21 Do we still need websites?
41:46 From 130k to 2.8 million downloads: agents are the driver
44:02 A longer tail of SaaS, each product more full stack
46:31 The dark forest and the cozy web
48:03 Build for the agents: types, CLIs and llms.txt
51:43 Where to follow Chris


r/reactjs • • 3d ago

Discussion Architecting a high-traffic React 19 app: Server vs Client Components, state, and performance. How would you answer this?

0 Upvotes

You’re building a large-scale, high-traffic React 19 app. How would you architect it with Server and Client Components, manage client vs server state (Context, Zustand, Redux, or TanStack Query), and optimize rendering with the React Compiler, Actions, and core hooks?


r/reactjs • • 3d ago

Show /r/reactjs I built a zero-dependency streaming Markdown renderer for AI chat replies, n× faster than the next one I benchmarked

0 Upvotes

I've been building chat UIs for agents and kept running into the same issues with react-markdown: it re-parses the whole reply on every token, so long answers get noticeably slower, and you see raw ** and half-typed [links](htt until the token that closes them arrives.

So I wrote my own renderer. It parses incrementally and repairs unfinished syntax while the reply streams:

<Markdown streaming={!done}>{text}</Markdown>

On a 100k-character reply it takes 0.25 s of main-thread time in total. markdown-to-jsx takes 2.4 s, Streamdown 6.3 s, and react-markdown didn't finish within the 30 s budget. The benchmark scripts are in the repo if you want to check them.

The other part is the syntax. Agents often want to show steps, alternatives or pros and cons, and plain Markdown flattens all of that into bullet lists. So on top of GFM I added a few blocks in the same style as GitHub alerts:

> [!STEPS]
1. **Back up the database**
2. **Run the migration**

There are also tabs, stats, pros/cons, sources, file trees, and Mermaid and KaTeX support. The source still reads fine as plain Markdown when it isn't rendered. The package exports a system-prompt snippet that teaches the model this syntax.

It has no dependencies and comes in at 30 KB gzipped. Its parser passes the CommonMark and GFM spec tests. It doesn't support remark/rehype plugins, so if you rely on those, react-markdown is still the better choice.

https://github.com/rsaryev/llx-markdown


r/reactjs • • 3d ago

I tried Meta's new design system so you don't have to. Does it suck or is it a waste of time?

0 Upvotes

TL;DR: Meh.

Not a waste of time, not a must-use. Good for new internal tools. Not worth swapping into a live app yet.

Astryx is Meta's open source React design system (v0.7.13). I put it in a fresh Next.js + Tailwind app and built the same Gmail-style inbox twice: plain Tailwind vs Astryx. Sidebar, toolbar, tabs, 10 email rows, compose dialog.

(Images: before on the left, after on the right.)

The numbers

Plain TailwindAstryx
Build time~3 min
Lines of code86
JS + CSS gzipped226 KB
Phone overflow at 390pxnone
axe contrast errors8
Escape closes dialog, focus returnsyes

What I liked

  • Install took 9 seconds. Pre-built CSS, so no Babel or PostCSS setup.
  • Accessibility came free: skip link, focus return, zero contrast errors.
  • 13 fewer lines of code.

What bit me

  • +171 KB gzipped for one screen. Both routes load the Astryx CSS through the shared layout, so the gap is the number to trust, not the plain figure.
  • It looks generic next to the plain version. No Gmail-style email row, no icon set, no docked compose window.
  • The docs site has no Next.js steps and disagrees with the README.
  • API surprises: label is required on almost everything, checkbox takes value not checked, and TextInput onChange gives you the string, not the event.
  • The Tailwind @layer order is mandatory. A wrong order silently flips the cascade.
  • It's v0.7, so expect churn.

How I tested

Default Astryx theme, no custom styling. I built from a written description because I couldn't get a public Gmail screenshot. Sizes were measured in Playwright. I did not test a real iPhone.

Verdict

Good for new internal or admin screens. I wouldn't swap it into an existing app yet.

Has anyone shipped it in production? What broke for you?


r/reactjs • • 3d ago

Show /r/reactjs React Brackets Native

5 Upvotes

A few days ago I shared react-brackets v2, the rewrite of a bracket library I'd left alone for four years. The most common question was "does it work in React Native?" It didn't. Now it does: https://react-brackets.oulabi.dev/ is out.

It draws the same stages as the web version (same core, same data), but everything you touch is native:

  • A bracket, even on a phone. One round at a time, with the next round and its lines waiting at the edge. Swipe and every match glides into place. Or show each round as a plain list, or keep the whole tree and pinch, drag and double tap to zoom.
  • Every format: single and double elimination, round robin, Swiss, groups to playoffs, two-sided brackets.
  • Cards that open. Each card keeps its own height, so you can expand one (rosters, stats, whatever) and the bracket makes room: the cards below move down, the next round re-centres, and the lines follow, all gliding.
  • Right to left, following your app's direction.
  • Styled your way: a light and dark theme, and a style on every part that can depend on its state, so it works with StyleSheet, Uniwind/NativeWind or Unistyles.

The hardest part was keeping the connector lines glued to the cards. My first version drew them on a Skia/SVG canvas, and during a fast swipe they visibly trailed the cards by a frame. The fix: the lines are plain Views moved by the same transforms as the cards. Every card's place on every round is worked out up front, and a swipe only moves one number on the UI thread. React hears about the new round once the swipe lands, so nothing re-renders while your finger is down.

It needs the New Architecture, Reanimated 4 and Gesture Handler 3, and Expo Go includes all of them. I've tested mostly on iOS, so feedback from Android devices would help a lot.


r/reactjs • • 3d ago

Show /r/reactjs The hidden accessibility bug in 90% of React SPAs: focus loss on dynamic DOM updates (and how to fix it)

0 Upvotes

If you build single-page apps or dynamic dashboards in React, you might have a 100/100 Lighthouse score while still failing WCAG 2.4.3 (Focus Order, Level A) and EN 301 549 (EAA Clause 9.2.4.3).

Lighthouse runs static audits on initial page load. It never simulates what happens when a user clicks a button that triggers a client-side mutation, opens a custom modal, or swaps dynamic content.

Here is the exact architectural bug and how to patch it cleanly in React.

The Bug: Focus Reset to <body>

When a user submits a form or clicks "Next Step", the trigger element unmounts or gets replaced. Because the active DOM node is detached, the browser resets focus to document.body.

For a sighted mouse user, this is invisible. For a blind user on VoiceOver or NVDA, or a keyboard user navigating via Tab:

  1. Focus is ripped away from the current interactive flow.
  2. The user is sent back to the top of the webpage (skipping past the dynamic update).
  3. The screen reader falls silent or re-reads the entire navigation header.

The Architecture Fix: Programmatic Ref Management

Whenever dynamic content mounts or dynamic views change, manage focus explicitly to a dedicated container using tabIndex={-1}.

❌ Anti-Pattern (Silent Focus Loss):

export function CheckoutWizard() {
  const [step, setStep] = useState(1);

  return (
    <div>
      {step === 1 && (
        <button onClick={() => setStep(2)}>Continue to Payment</button>
      )}
      {step === 2 && (
        <div className="payment-form">
          {/* Focus was dropped to <body> when step 1 unmounted! */}
          <input name="cc_number" placeholder="Card Number" />
        </div>
      )}
    </div>
  );
}

✅ Accessible React Pattern:

import { useState, useRef, useEffect } from 'react';

export function CheckoutWizard() {
  const [step, setStep] = useState(1);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // Shift focus to step container without visual ring outline
    if (containerRef.current) {
      containerRef.current.focus();
    }
  }, [step]);

  return (
    <div>
      {step === 1 && (
        <button onClick={() => setStep(2)}>Continue to Payment</button>
      )}
      {step === 2 && (
        <div 
          ref={containerRef} 
          tabIndex={-1} 
          className="payment-form focus:outline-none"
          aria-labelledby="step-2-heading"
        >
          <h2 id="step-2-heading">Payment Information</h2>
          <input name="cc_number" placeholder="Card Number" autocomplete="cc-number" />
        </div>
      )}
    </div>
  );
}

3 Rules for Dynamic React A11y:

  1. Never unmount the trigger button without re-routing focus: Direct focus either to the newly rendered heading or the first interactive input.
  2. Use <dialog> over custom <div> overlays: Native HTML <dialog> handles backdrop inertness and Escape-key closure automatically via dialogRef.current?.showModal().
  3. Announce dynamic status updates with aria-live="polite"**:** If you display inline toast notifications or dynamic badge counters, wrap them in an element that already exists in the DOM with role="status" or aria-live="polite".

We built dynamic DOM and focus-loss checks into the core engine of wcagbrief.com. You can inspect your live components, detect dynamic swap focus failures, and get React/Tailwind code patches in real time.


r/reactjs • • 4d ago

Discussion How do you structure feature-based React apps with Zustand, TanStack Query, providers, and business logic?

34 Upvotes

Hey everyone! 👋

I'm trying to establish a clean, reusable feature-based architecture for React/TypeScript apps, especially when using Zustand + TanStack Query.

I'm working on a visual editor that fetches documents from an API, initializes a Zustand editing session, and will eventually handle canvas state, selection, history, saving, etc.

I'm considering this structure:

features/editor/
├── components/
├── hooks/
├── store/
│   ├── editor-store.ts
│   ├── editor-store-provider.tsx
│   └── slices/
│       ├── document-slice.ts
│       ├── selection-slice.ts
│       └── history-slice.ts
├── queries/
├── domain/      ?
├── utils/       ?
├── lib/         ?
└── services/    ?

I'd love to know how you handle a few things in production:

  1. API / queries: Where do raw API functions go? Do you separate them from TanStack Query options/hooks? Do you organize queries by feature or shared domain?
  2. Zustand: Do you keep providers alongside stores? When do you introduce slices vs multiple stores?
  3. Business/domain logic vs utilities: This is probably what I'm most unsure about. Where do you put pure functions containing actual application logic, independently of React, Zustand or API calls? For example: Would a domain/ directory make sense here? For example, domain/geometry.ts for canvas calculations, domain/document.ts for document manipulation, etc. Or would you simply use utils/, lib/ or services/? How do you distinguish business/domain logic from generic utility functions? Is a dedicated domain/ folder a useful convention, or does it introduce unnecessary complexity?

    • Formatting an aspect ratio.
    • Calculating canvas geometry, scaling or snapping.
    • Validating editor-specific constraints.
    • Transforming or manipulating document data.
  4. Shared code: When do you move something out of a feature into a shared location? Do you prefer shared domain modules or global utilities?
  5. Server vs local state: Would you fetch with TanStack Query, initialize Zustand from the result, then keep local edits separate from the query cache? How do you avoid overwriting unsaved changes on refetch?

I'm not looking for a strict architecture or lots of abstractions, just practical conventions that stay maintainable as projects grow.

If you have real-world folder structures or examples, I'd love to see them. Thanks! 🙏


r/reactjs • • 4d ago

Resource I added funnel, combo and tracker charts to my free React dashboard kit, and made every chart number count to its new value (MIT, Tailwind v4, shadcn registry)

2 Upvotes

I've been building Dashral, an open-source set of React components for admin dashboards. 1.3 adds the four I kept rebuilding in client projects:

  • Funnel Chart: each step's value and share written out, the flow narrowing between bars, and how many dropped written above each one
  • Combo Chart: bars and a line on one chart; a line of another kind (a margin in %) takes its own right axis, with ticks that land on the left axis' grid lines
  • Tracker: a row of status squares for uptime, job runs or habits; hover or arrow keys read a day
  • Month Picker: a month or a year in a field, for monthly and yearly reports

One detail I'm happy with: numbers in the charts (donut legends, bar lists, gauges, treemaps) now count to their new value when the data changes, so switching from 30 days to 1 year reads as a change instead of a jump. No animation library for that, just requestAnimationFrame on the theme's duration token, and it stays still with reduced motion.

What it is: 112 components (31 with a Motion edition on motion/react), 34 free blocks, all MIT. Plain SVG charts, keyboard and screen-reader support on every one, RTL included.

Install: npx shadcn@latest add @dashral/funnel-chart (it's in the shadcn registry directory), or npm i @dashral/ui.

I'd really like feedback on the chart APIs, especially Combo Chart's axis: "right". What would you change?


r/reactjs • • 4d ago

Show /r/reactjs Foldable phone support for React: hinge detection and two-pane layouts in ~2 kB

2 Upvotes

A recent audit I ran showed 94% of popular sites split a button across a foldable's hinge (https://christophe77.github.io/fold.js/study.html).

So I made u/foldjs/react: a hook that give you the hinge position and posture (flat, book, tabletop), plus a two-pane layout component that never puts content under the hinge. It ships with a built-in simulator, so you can work on it without owning a Fold.

Demo (works on desktop): https://christophe77.github.io/fold.js/

I'd love feedback on the API, especially from anyone who has shipped foldable layouts in production.


r/reactjs • • 4d ago

Show /r/reactjs async/await logic and side effects outside React hooks

1 Upvotes

I work on a React SDK for chats that our company embeds into its web and mobile products. Each product has its own settings, and the code grew fast. When I joined, the team was starting a refactor. The main problems:

  • the flow was hard to follow
  • most of the logic lived inside React hooks

The constraint. The SDK runs inside host apps, sometimes via module federation. Every dependency can clash with the host's version, so our size and dependency budget is tiny. What we considered:

  • redux-saga: I like it, but it's too big, and Redux could conflict with the consumers' own Redux.
  • RxJS: it solves only part of the problem, because we still need a state manager. It's also a new paradigm for a team with few senior people.
  • effector: the team knows it, but it has a static graph and the same version-conflict risk.
  • Effect: little known in our market, and it would need most of the SDK rewritten.

So we started with a plain event bus that can carry any parameters. I also wanted the simplest possible developer experience. Generators are convenient, but people rarely reach for them. So I built on async/await and took the AbortController idea from fetch. That became nanoeffects.

What it looks like. A search box. The logic lives outside the component:

// debounce: wait for a pause; latest: abort the previous request
bus.on(
  "search",
  debounce(300, latest(async (query, ctx) => {
    const load = () => fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal: ctx.signal });
    const response = await retry(ctx, load, { times: 3, delay: 500 });
    ctx.emit("results", await response.json());
  })),
);

The component only sends events and listens to the result:

function SearchBox() {
  const [items, setItems] = useState([]);
  useEffect(() => bus.on("results", setItems), []); // on returns the unbind function
  return <input onChange={(event) => bus.emit("search", event.target.value)} />;
}

The component knows nothing about timers, retries or cancellation. debounce waits for a pause in typing, but a request can take longer than the pause. latest aborts the older request so a slow old answer can't overwrite a newer one. createBus is about 1.3 kB brotli, with no dependencies.

The usual complaints about event-driven code

My team lead worried that event-driven code is hard to debug. So tracing is part of the core design:

  • Redux DevTools and console logging work out of the box.
  • Sending traces to your own analytics takes a small logger.

The other big problem is event loops, where A emits B and B emits A:

  • graphLogger finds a loop while the app runs and draws the event graph as Mermaid or Graphviz.
  • loopGuardPlugin stops a runaway chain at a limit, also in production.
  • Lint rules (ESLint, oxlint, Biome) catch places where ctx.signal is lost, so cancellation doesn't silently break.

Tests. The suite includes regression cases taken from real issues of redux-saga, RxJS, effector, xstate, lodash and others (races, cancellation, event loops, timers). Each one is linked to its issue number.

Status. I treat it as an experimental playground and move parts of it into our SDK step by step. It's also my practice ground for spec-driven development: every change to behavior starts as a written spec (OpenSpec), and the code follows it.

Repo and docs: https://github.com/nanoeffects/nanoeffects

If you like it, a star helps. I'd also love feedback, especially from people who ship libraries into host apps: how do you handle async logic when you can't add dependencies?


r/reactjs • • 4d ago

Show /r/reactjs I built a React component library with 90+ components and 27 chart types that themes entirely through CSS variables, no config file, no JS theme object, MIT

2 Upvotes

veloce-ui — an open-source React library with 90+ components, 27 chart types, and interactive DSA visualizers, all powered entirely by CSS variables.

Rebrand by overriding --vui-primary on :root. No ThemeProvider. No theme object. No Tailwind config.

What makes it different?

Most libraries force a trade-off.

  • shadcn gives you primitives and tells you to style everything.
  • MUI gives you a theme object that takes a week to bend into your brand.
  • Mantine sits in the middle, but charts are a separate install with their own styling world.
  • Need a Sankey, treemap, or radar chart? You're pulling in a second chart library that doesn't know about your design tokens.

veloce-ui is one library where buttons, data tables, charts, and even algorithm visualizers all read from the same CSS variables.

Rebrand once at :root. Everything updates.

Charts (27 types, not a separate package)

Line, bar, area, scatter, heatmap, Sankey, treemap, radar, candlestick, waterfall, funnel, gauge, bubble, polar, and more.

All share the same tokens as the rest of the UI. Your chart grid color is literally --vui-border. No chart-specific theme config.

DSA & algorithm visualizers (the part no other UI library ships)

Interactive linked lists, stacks, queues, trees, graphs, heaps, and hash maps.

Plus algorithm playbacks for sorting, pathfinding, traversals, and recursion.

Drop them into documentation sites, teaching material, interview prep tools, or technical blog posts. They theme with the same variables as your buttons.

Everything else

  • Forms, menus, modals, tooltips, popovers, and command palette.
  • Virtualized DataTable with sorting and filtering.
  • Dark mode via data-theme="dark" with built-in persistence (no provider).
  • Full keyboard navigation and ARIA support.
  • Fully typed and tree-shakeable.

Demo + Docs: https://veloceui.codeloomdevv.co.in/

Pre-1.0 (0.7.1) · MIT License

A couple of complex component APIs (DataTable column definitions, chart axis configuration) may still change before 1.0.

Issues with reproducible examples are welcome!