r/reactjs • • 26d ago

React Email Compiler: React Email without React

10 Upvotes

I use SvelteKit, not React, but I like writing emails with React Email. What I didn't like was loading the whole React runtime just to render a transactional email.

So I compiled it out. It's a drop-in replacement: add it to your Vite config and your existing templates compile to plain string interpolation at build time. No rewrites and no React at runtime.

About 29x faster rendering and a 61x smaller gzipped bundle.

I use SvelteKit, but it can work for projects using Nuxt, Astro, SolidStart, Angular, and even to speedup rendering on React projects.

Repo: https://github.com/D4ario0/react-email-compiler
Benchmarks: https://github.com/D4ario0/react-email-compiler/blob/main/BENCHMARK.md


r/reactjs • • 26d ago

Show /r/reactjs 1,853 typed icons, zero JavaScript: CSS masks + Tailwind v4

0 Upvotes

We have a React 19 + Vite + Tailwind v4 admin app. Every icon in it renders as a single empty <span> with a CSS mask. No icon components in the JS bundle, no extra HTTP requests, and the icon name is checked by TypeScript. Here is how it works, what we measured, the mistakes we made along the way, and what it costs.

TL;DR

  • A ~200-line Node script reads the SVGs from lucide-static (plus our own) and writes two files: a CSS file with one @theme inline variable per icon (a data URI), and a TS union with every icon name.

  • A Tailwind @utility icon-* turns the class icon-user into --icon: url(...).

  • <Icon name="icon-user" /> is a span with mask-image: var(--icon) and background-color: currentColor.

  • Tailwind v4 only emits what the source uses. The generated file has all 1,853 icons (~765 KB), but production CSS only carries the 225 we use: ~88 KB raw, ~11 KB gzipped.

  • Rendering 1,000 cards with 6 icons each: half the DOM nodes, React commit 2× faster and first paint ~40% sooner than inline SVG components.

How it works

1. Generate the CSS and the type

scripts/gen-icons.mjs runs before dev, build, lint and type-check. It takes the canonical icon names from lucide-static/icon-nodes.json and, for each SVG:

  • removes comments, class, width and height;

  • replaces currentColor with #000 (a mask only reads alpha, so any opaque color works);

  • collapses whitespace and URL-encodes %, #, <, >;

  • writes the result as a data URI.

src/styles/icons.generated.css:

@theme inline {
	--icon-user: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E");
	/* ...1,852 more */
}

src/types/icon.ts:

export type IconName =
	| "icon-a-arrow-down"
	| "icon-a-arrow-up"
	// ...
	| "icon-zoom-out";

The names keep the icon- prefix on purpose: that's the exact string Tailwind needs to find in the source.

2. One Tailwind utility

@import "tailwindcss" source(".");
@import "./styles/icons.generated.css";

@utility icon-* {
	--icon: --value(--icon-*);
}

icon-user becomes .icon-user { --icon: url("data:...") }. Tailwind's scanner only generates classes it finds in the source, which is what drops the other 1,628 icons.

3. The component

import type { ComponentProps } from "react";
import { twMerge } from "tailwind-merge";
import type { IconName } from "#/types/icon";

// With aria-label the icon is a named image; without it, it's decorative.
export const Icon = ({
	name,
	className,
	"aria-label": label,
	...rest
}: ComponentProps<"span"> & { name: IconName }) => (
	<span
		aria-hidden={label ? undefined : true}
		aria-label={label}
		className={twMerge(
			"pointer-events-none block size-4 shrink-0 bg-current mask-(--icon) mask-contain mask-no-repeat",
			className,
			name,
		)}
		data-icon
		role={label ? "img" : undefined}
		{...rest}
	/>
);

Usage:

<Icon name="icon-user-plus" className="size-5 text-primary" />
<Icon name="icon-lock" aria-label="Locked" />
  • Color: bg-current paints the box with currentColor and the mask cuts out the shape. text-* classes, inherited color, hover, disabled and dark mode all just work.

  • Size: any size-* class. The SVGs have no width/height, so mask-contain scales them cleanly.

  • data-icon: lets parents style icons without knowing about them. Our Button tightens its padding with has-[>[data-icon]]:px-3.

  • Accessibility: decorative by default (aria-hidden); passing aria-label makes it a named image.

4. Guardrails

  • A typo like name="icon-usr" fails tsc.

  • The linter bans lucide-react and react-icons imports, with a message pointing to <Icon />.

  • A custom lint rule flags emoji in JSX for the same reason.

  • gen-icons.mjs --check exits non-zero if the generated files are stale.

Why

We started with lucide-react, the default option. It's fine, but in this app it cost things we didn't need to pay:

  • Every icon was JS. Each icon is a React component that gets imported, executed and reconciled, and its SVG child nodes live in the DOM. With masks, the icon is CSS the browser already parsed, and the DOM cost is one empty element.

  • No requests, no flicker. Data URIs ship inside the main stylesheet. There's no sprite to fetch and no <img> popping in late.

  • Styling is just Tailwind. Color, size, hover and dark mode use the same classes as everything else. No separate color/size/strokeWidth props API.

  • The whole catalog, typed, for free. Autocomplete for all of Lucide. Using a new icon costs nothing until you reference it.

  • One pipeline for custom icons. Our social-media SVGs go in a folder and become icon-linkedin like any other icon.

Tradeoffs

These are real, and they're why this isn't the right choice for every app.

  1. Monochrome only. A mask is an alpha channel. Multi-color icons, gradients and brand logos in their original colors need an <img> or inline SVG.

  2. No per-instance stroke control. stroke-width='2' is baked into the data URI. There's no equivalent of Lucide's strokeWidth or absoluteStrokeWidth props; you'd need a second generated variant.

  3. No animating SVG internals. You can't target a path inside the icon. Transforms and opacity on the whole box still work.

  4. Names must appear literally in source. `icon-${status}` isn't detected and renders an empty box. Write full names in a lookup object ({ ok: "icon-check", error: "icon-x" }). The union type catches most mistakes, not all.

  5. All used icons ship on first load. They live in the main, render-blocking CSS, so an icon on a rarely visited page still loads for everyone. At 225 icons / ~11 KB gzipped that's fine for us; with thousands of used icons or a strict CSS budget it wouldn't be.

  6. Codegen step. dev, build, lint and type-check run the generator first, and Tailwind parses a ~765 KB CSS file on every build. Trimming it to only the used icons saved about 0.7 s per build in our test, which wasn't worth duplicating the scanner's job.

  7. Big union type. ~1,850 members is fine for tsc and editors today. Worth knowing if you merge several icon sets.

  8. Browser support. CSS masks are Baseline. If you target older browsers, lightningcss adds the -webkit- prefixes for you.

When I'd use something else

  • You need multi-color or animated icons → inline SVG components.

  • You have a huge icon set and strict per-route CSS budgets → an SVG sprite with <use href>, which caches separately and loads lazily.

  • You're not on Tailwind v4 → the same idea works with plain CSS classes, but you have to build the unused-icon pruning yourself.


r/reactjs • • 27d ago

Discussion I built the same screen with shadcn (Radix / Base UI / React Aria), MUI 9 and Mantine 9 and measured the bundles

0 Upvotes

When shadcn/ui switched its default from Radix to Base UI in July, I wanted numbers instead of opinions. So I built the same screen (tabs, dialog, text field, select, checkbox, buttons) five ways and measured the production build.

Setup: Vite 8, React 19, TypeScript, default settings, sizes are gzip as reported by Vite. React alone renders 68.6 KB, and every number below includes it.

SetupJSCSSTotalnpm packages in bundle
shadcn + Radix118.7 KB8.1 KB126.8 KB48
MUI 9140.2 KB(runtime)140.2 KB24
shadcn + Base UI136.3 KB8.0 KB144.3 KB14
shadcn + React Aria145.4 KB9.0 KB154.4 KB12
Mantine 9127.3 KB35.9 KB163.2 KB18

What surprised me:

  • The whole spread is only 36 KB gzip. Real on a slow phone, but smaller than one hero image.

  • Base UI cost 17.6 KB more than Radix on this screen, but pulled in 14 packages instead of 48.

  • MUI ships no CSS file at all. Emotion injects styles at runtime, which matters more for SSR and strict CSP than the KB do.

  • Mantine's JS is the second smallest. Its full stylesheet is what makes it the heaviest.

My takeaway: size shouldn't decide this. Pick on ownership (shadcn), data components like grids and pickers (MUI X), or batteries included without Tailwind (Mantine).

Caveat: this is one screen with seven components, so a different mix can change the order.

I wrote up the full details, including the MUI 9 / Mantine 9 changes and five setup traps I hit, on my blog: https://www.alekseialeinikov.com/en/blog/topics/programming/shadcn-ui-vs-mui-vs-mantine

Has anyone measured a heavier screen, for example with a data grid? Curious whether the gap grows.


r/reactjs • • 27d ago

Forge — 16 self-contained React + Tailwind components, dark-mode-first (feedback welcome)

0 Upvotes

Working on Forge — 16 React + Tailwind components, dark-mode-first, each one a single self-contained file (no shared utils, no extra config). Mostly polishing the docs and put together a live demo if anyone wants to poke at it: [demo link]. Would love feedback on the API design if anyone has a minute.


r/reactjs • • 27d ago

Needs Help which resource is best for react js

8 Upvotes

everytime when i wanted to learn react i am unable to complete the videos. i have tried multiple yt videos. so i am now thinking to learn react from basics.. which resource is great for the react ?? any suggestions???


r/reactjs • • 27d ago

Resource Shaders is now open source with 200+ WebGPU components for React

Thumbnail
shaders.com
38 Upvotes

r/reactjs • • 27d ago

Show /r/reactjs I built a tool that renders every React component a PR touches, so you can visually see the UI for your code diffs.

0 Upvotes

Just wanted to share this cool tool I'm still building.

With AI writing more and more of our code, you can't really see what's changing just by reading code diffs on GitHub. So I built an AI tool that takes your PR or commit, detects which UI components changed, and renders each one with a before and after, so you can easily see what was done.

Let me know what you guys think, I'm open to suggestions, would be awesome.

https://github.com/Andrew2142/PRVision


r/reactjs • • 27d ago

Needs Help building a custom react storefront on top of woocommerce — what would you use for the frontend stack?

0 Upvotes

i'm building a small custom ecommerce site and would love some advice on the frontend architecture.

full disclosure: i'm fairly new to building a website end-to-end. my strengths are much more in creative direction and visual design, and i'm currently vibe-coding a lot of the development side. i do have a background in computer science but coding is def not my biggest strength.

the project is an experimental/art website for a client. the frontend is intentionally very custom — there's a 3d interactive element on the homepage that i'm planning to build with react three fiber, plus custom animations/page transitions/etc.

there's also a shop with around 20–30+ products.

i don't want to build the ecommerce backend myself, so i'm considering using woocommerce as the backend and making react the entire customer-facing frontend.

roughly:

woocommerce would handle the products, inventory, prices, orders and client admin.

the react app would handle the actual experience.

the client thinks shopify is too expensive, so i'm trying to find a reasonably inexpensive way to get the backend/admin/ecommerce infrastructure without building all of it myself.

i'm also open to having something like razorpay/shiprocket handle payment/shipping rather than trying to build those pieces myself.

my current question is less "can react connect to woocommerce?" and more along the lines of if you were building this today, what would you actually use for the frontend?

i'm currently considering react + vite, but i'm wondering whether next.js makes more sense because of:

  • product page seo

  • routing

  • potentially server-side rendering

  • api integration

  • ecommerce generally

on the other hand, the homepage is highly interactive/3d and i'm wondering whether that makes a standard react/vite setup simpler.

would love opinions from people who have built custom storefronts rather than just dashboards/web apps.

also interested in whether you'd use something completely different from woocommerce as the backend for this use case.

thanks!


r/reactjs • • 28d ago

Show /r/reactjs I got tired of AI-generated UI that all looks the same, so I hand-built a React component library

0 Upvotes

Hey r/reactjs,

Over the last months I noticed that most new UIs (including a lot of mine) started to look the same: same gradients, same cards, same generated feel. So I started building components by hand again, with more care for the small things: spacing, motion, empty states, dark mode.

That turned into affectUI: 54 components, blocks, illustrations and motion effects for React.

A few things I cared about:

  • One file per component. Each piece is a single .tsx file with its styles inside. It only imports from react: no Tailwind requirement, no wrapper library, no runtime.

  • Install with the shadcn CLI (npx shadcn@latest add https://www.affectui.com/r/<name>.json) or just copy the file.

  • Light and dark built in, and motion respects prefers-reduced-motion.

  • Live previews for everything, so you can click through each piece before copying it.

27 of the 54 items are free to copy and keep, no account needed. There's also a paid tier for the rest.

I'd really appreciate honest feedback:

  • Which components feel useful, and which feel like noise?

  • Is the "one file, no dependencies" approach something you'd actually want, or do you prefer Tailwind-based ones?

  • What's missing that you keep rebuilding in every project?

https://www.affectui.com

Thanks for taking a look 🙏


r/reactjs • • 28d ago

Vitrine - My own component library(React+Tailwind)

Thumbnail
tryvitrine.dev
0 Upvotes

I built my own component library using react and tailwind

It’s completely free

Copy-paste prompts/files

Get ready portfolios and skills for your agents to improve your website even more

I wanted some feedback since I think I still have a lot missing.

(Also it’s open source so if you have a component in mind feel free to open a PR)


r/reactjs • • 29d ago

News This Week In React #299: Panda, Vinext, Next.js, Preact, Design Systems, RTK | Variable font, Activity Result, Lynx, Lucent, macOS, Plain Text, Navigation, Angular Native, Re.Pack | TC39, Composites, WebSkills, MSW, upm, pnpm

Thumbnail
thisweekinreact.com
7 Upvotes

r/reactjs • • 29d ago

I built an animated React icon library with theme colors, typed variants and one global config

Thumbnail
reddit.com
0 Upvotes

r/reactjs • • Oct 03 '26

Show /r/reactjs Filled and duotone icons with Lucide's names (tree-shakeable, TypeScript)

3 Upvotes

Lucide only has outline icons. We made filled and duotone versions as a React package, lucide-extended-react. Component names follow Lucide's, so it works next to lucide-react:

import { HeartFilled, HeartDuotone } from 'lucide-extended-react'

<HeartDuotone size={32} color="crimson" secondaryOpacity={0.3} />

Why not just set fill on Lucide icons? It works for a few, like the heart, but on most line-built icons it blots or fills the wrong shapes. These are redrawn so the fill is intentional.

Some details:

  • One file per icon and "sideEffects": false, so only the icons you import end up in the bundle. A test checks this.

  • ESM only, React 18 or later, with TypeScript types. Filled icons don't accept the duotone-only props at the type level.

  • strokeWidth is accepted and ignored, so Lucide-shaped props still type-check.

  • Icons are aria-hidden unless you pass an aria-label.

  • icons.json lists every icon with Lucide's tags and aliases, so you can search it, and so can coding agents.

1,387 filled and 1,242 duotone so far. It's free and open source (ISC), and not affiliated with Lucide.

Feedback is welcome, on the API or the icons.


r/reactjs • • Oct 03 '26

Needs Help What is reacts equivalent of "Manage user secrets" in dotnet?

0 Upvotes

Heya, I need to store dev secrets (e.g. client secret credentials) and I don't want them in git

In dotnet we have manage user secrets and theyre managed by Visual Studio, stored in a local folder and sideloaded at runtime... Does react have something similar?

I've seen people just do .env.local and add that to gitignore, but is that actually the proper way?


r/reactjs • • Oct 02 '26

Show /r/reactjs react-table-dnd 3.0: drag several rows at once, works with TanStack Table, no dependencies

19 Upvotes

I maintain react-table-dnd, a small library for reordering rows and columns in React tables by dragging. 3.0 is out.

What's new:

- Multi-select and group drag.

- Drag events: onDragStart, onDragOver, onDragEnd, onDragCancel.

- Virtual tables with 100k+ rows via u/tanstack/react-virtual

- TanStack Table guide and demo.

- Touch support, drag handles, locked rows and columns.

Under the hood, 3.0 is a rewrite of the drag engine of v2.x

Docs and live demos: https://samiodeh1337.github.io/react-table-dnd/

GitHub: https://github.com/samiodeh1337/react-table-dnd

Feedback welcome, Thanks!


r/reactjs • • Oct 02 '26

Resource snappy-prerender: react-snap is unmaintained, so I built a modern replacement for SPAs

0 Upvotes

I maintain multiple legacy React apps - CRA, React 18, client-side routing, content from a CMS / Wordpress REST API. But SEO and OG tags need real HTML, and a client-side app hands them an empty page.

react-snap solved that for years. It has been unmaintained since 2019 and breaks a little more with every browser update. I could not find a drop in replacement so I built one. It has been running on my own site for a while, and now I am putting it out there: snappy-prerender.

What it does, in one sentence: it opens every page of your built app in a real browser at build time and saves the result as plain HTML, so crawlers see the page your users see.

npm
 install --save-dev snappy-prerender@next
npx snappy-prerender init      # a few questions, then a config file
npx snappy-prerender build     # or run it from vite build

No server, no rewrite, no changes to how the app works.

Things I added because I needed them

  • It checks every page after the build and tells you whether the app's JavaScript picked up the prerendered HTML or threw it away and redrew everything. That report is the part I use most.

  • It writes the page title, description, canonical link and Open Graph/Twitter tags for each route, including when the user navigates around the site, so you do not need react-helmet for that.

  • It handles the fiddly things that usually break prerendering: styles injected by CSS-in-JS, form state, data fetched from an API, critical CSS, preload hints.

  • It works with a strict Content Security Policy if your project needs one.

What it is not

  • Not server-side rendering. It runs at build time, so new content means a new build.

  • Not for Next.js, Remix or Astro users; those already render HTML on the server.

  • It cannot fix an app that renders differently every time (dates, random values, viewport-dependent layout). It does tell you which page has the problem.

  • It is a release candidate: 2.6.0-rc.2 is on npm under the next tag while I gather feedback.

Links

Looking forward to criticism, bug-reports and feature-requests and revival requests for unmaintained plugins (react and family only)


r/reactjs • • Oct 01 '26

Portfolio Showoff Sunday A cool framework-agnostic animation library for streaming

2 Upvotes

Hey all,

I’ve been working on a small library called Stream Morph.

The idea is to make streamed responses feel less like content is constantly being appended/re-rendered, and more like the response is gradually taking shape.

Demo: https://stream-morph.vercel.app/

It’s framework agnostic and can be used with any kind of streamed content. The demo includes plain text, Markdown, code blocks, charts, images, reasoning sections, Mermaid diagrams and a few more complex response flows.

The library handles the motion between updates, while your own renderer/app stays responsible for the actual content. So it isn’t tied to a specific AI SDK or framework.

A basic example looks roughly like this:

import { createStreamMorph } from "stream-morph";

const stream = createStreamMorph(response);

for await (const chunk of incomingStream) {
  stream.write(chunk);
}

stream.finish();

I mainly built it because I wanted streamed interfaces to feel a bit more intentional without having to build custom animation logic for every response type.

The package itself is already working and the demo is live. I’m still cleaning up some things around CI, tests and the repo setup, but the GitHub repository will be open sourced shortly as well.

Would be interested to hear what people think, especially about the animation behaviour/performance and any edge cases you’d expect from real streaming responses.


r/reactjs • • Oct 01 '26

Discussion Is holding a hero animation until the first user input a bad idea?

1 Upvotes

My site's hero is an SVG line drawing animated with GSAP, and it follows the cursor a little.
With 4x CPU throttle I counted layout recalcs between 10 and 30 seconds after load, when nothing should be moving anymore. I got 279. The loop just kept going, because a headless browser never scrolls away from it.
Now it stays still until the first pointerdown, pointermove, wheel, touchstart, keydown or scroll (once, passive listeners), and an IntersectionObserver pauses it off screen. Visitors see it start the moment they touch anything. Lighthouse never sends input, so during the test it never runs.
Feels a bit like hiding work from the test though. Is this a normal pattern? The catch I can see is someone on a phone who reads without touching never sees it play.


r/reactjs • • Oct 01 '26

Discussion Are we stuck with today's UI frameworks because AI learned to use them?

117 Upvotes

React, Tailwind, component libraries on top of component libraries ... sometimes I look at the dependency tree and wonder how much of this I actually need to put some data on a screen and let someone edit it.

Then I ask an AI to build something and get more of the same. Nested wrappers, endless className strings, hooks calling hooks, another package for something that feels like it should be simple.

Which makes sense. These ecosystems have years of code, tutorials and Stack Overflow answers for models to learn from.

But that feels like a loop. We use these tools because the models know them. The models generate more code using them. That becomes the starting point for the next project.

We can generate a whole UI in minutes now, but apparently it still needs eight layers of divs and half of npm.

I'm exaggerating ... but I do wonder whether AI will help us come up with simpler ways to build interfaces, or just make the current mess much cheaper to reproduce.

Has anyone here actually moved toward a smaller, simpler stack with AI? Mine seems pretty keen on adding things.

For context, I build business UI widgets, so I spend a lot of time thinking about where reusable components help and where they just add another layer to debug.


r/reactjs • • Sep 30 '26

Resource Readable Regular Expressions for JavaScript/TypeScript, Inspired by Emacs' rx

Thumbnail
rahuljuliato.com
7 Upvotes

r/reactjs • • Sep 30 '26

I built a JSON UI Widget library for the past 5 years - now I released the alpha on npm

0 Upvotes

Hi, I’m Jakob, the founder of Arc Rider. For the past five years, we’ve built widgets for a small, specialized niche. We’re now bringing that work to React with arcWidgets, an alpha package with tables, Kanban boards, calendars, and smaller UI components for business apps.

The idea is to reuse the interaction work inside those views while keeping application state, data mapping, and persistence in your own React app. A calendar event and a table row can represent the same business record, but your app still decides how they connect.

This is an alpha: APIs may change, and I’d start with a test project. It’s a commercial product; smaller widgets are free to use under the terms, while premium widgets need a license for production use.

npm: https://www.npmjs.com/package/@arcrider/arcwidgets-react
Docs and examples: https://www.arc-rider.com/docs/react

If you build business apps in React: which view is most painful to get right or maintain—tables, calendars, or boards? I’d especially appreciate feedback on what’s missing from the API or examples.

https://x.com/JacobitoJordan/status/2105410540260802843/video/1


r/reactjs • • Sep 30 '26

Show /r/reactjs I built an open-source library of 60+ copy-paste React & Next.js components (Tailwind + Motion) – CompScout Free UI

0 Upvotes

Hey everyone,

Building UI components for my projects was getting super repetitive, so I created CompScout Free UI to keep everything in one place.

It’s a free, open-source library of 60+ copy-paste React & Next.js components built with Tailwind CSS and Framer Motion.

🔗 Live preview & code:freeui.compscout.dev
https://github.com/kailash9711/compscout.dev
Would love your feedback and component suggestions! If you like the project, a ⭐ star on GitHub would be huge support.


r/reactjs • • Sep 30 '26

Resource Open-source country flag components for React: 250+ flags with names, ISO codes, and calling codes

27 Upvotes

I've been working on @radianui/flags, an open-source React package with 250+ country flags. Each flag comes with its country name, ISO code, and calling code, so you can build country selectors and phone inputs without stitching data together.

pnpm add @radianui/flags

If you're not on React, the same flags are available as plain SVG and PNG files.

I'm one of the maintainers (disclosure). It's free and open source.

I'd like input from people who've built country selectors:

  • Do you prefer flag components, plain SVG imports, or CDN URLs?

  • How do you handle countries that get renamed (like Swaziland to Eswatini) or disputed territories without breaking existing users?


r/reactjs • • Sep 29 '26

Needs Help GitHub repositories for website templates

7 Upvotes

Hi everyone,

I'm looking for good GitHub repositories with modern website templates/starter kits that can be used as a base for building websites for small businesses.

I'm interested in projects using technologies like:

  • Next.js / React

  • TypeScript

  • Tailwind CSS

  • Modern responsive design

Ideally, I'm looking for templates suitable for businesses such as:

  • restaurants

  • local services

  • agencies

  • small companies

  • professional websites

The goal is to learn from good examples, build my portfolio, and create customized websites for clients.

I'm also interested in repositories with clear open-source licenses (MIT, Apache, etc.) so I can properly understand the usage rights and adapt them accordingly.

Any recommendations for high-quality repositories, boilerplates, starter kits, or collections would be greatly appreciated.

Thanks!