Modern frontend development has a problem.
We keep rebuilding the same UI components — Selects, Toasts, Modals —
over and over again, just because the framework changed.
React today.
Vue tomorrow.
Maybe Qwik, Solid, or something else next year.
And every time, the UI stack resets.
I decided to stop playing that game.
This post is about why I built framework-agnostic UI components using native Web Components,
and why I believe this approach is not a niche experiment — but the future of UI primitives.
The Real Problem with Modern UI Libraries
Most UI libraries today are:
- ❌ Locked to a single framework
- ❌ Heavy on dependencies
- ❌ Painful to migrate away from
- ❌ Fragile in SSR environments
- ❌ Inconsistent in accessibility
Even “headless” libraries are still framework-bound.
The result?
UI logic becomes disposable every time your stack changes.
That’s unacceptable for long-lived products.
My Goal: UI That Outlives Frameworks
I wanted UI components that:
- Work everywhere
- Have zero framework lock-in
- Are small, fast, and predictable
- Support real-world features, not demos
- Treat accessibility and SSR as defaults, not add-ons
The answer was obvious:
Native Web Components.
Why Web Components (And Not Another Abstraction)
Web Components are:
- A browser standard
- Framework-agnostic by design
- Compatible with every modern UI stack
- Stable over time
No virtual DOM magic.
No render lifecycle traps.
No dependency graph explosions.
Just elements, events, and state.
What I Built
I started with the two components that cause the most pain in real projects:
- SeoSelect — a production-grade Select component
- SeoToast — a universal Toast notification engine
Both are built as pure Web Components, then wrapped for frameworks optionally.
- SeoSelect → https://www.npmjs.com/package/seo-select
- SeoToast → https://www.npmjs.com/package/seo-toast
SeoSelect: Not “Another Select Library”
Select components are deceptively complex.
Real apps need:
- Large datasets
- Fast rendering
- Search (multilingual, fuzzy)
- Keyboard navigation
- Accessibility
- Custom styling
- Type safety
So I built SeoSelect as a real Select engine, not a demo widget.
Key Features
- Zero dependencies (pure Web Component)
- Works with React, Vue, Angular, Solid, Qwik, Vanilla
- Virtual scrolling for large datasets
- Fuzzy multilingual search (Korean initial consonants, Japanese romaji, Chinese pinyin)
- Full keyboard & screen reader support
- CSS Variables for theming
- Typed events with global TypeScript support
Comparison: SeoSelect vs Popular Select Libraries
| Feature | SeoSelect | react-select | Headless UI | antd / Prime |
|---|---|---|---|---|
| Framework-agnostic | ✅ | ❌ | ❌ | ❌ |
| Vanilla JS support | ✅ | ❌ | ❌ | ❌ |
| Zero dependencies | ✅ | ❌ | △ | ❌ |
| Virtual scrolling | ✅ | ❌ | ❌ | △ |
| Multilingual fuzzy search | ✅ | ❌ | ❌ | ❌ |
| Accessibility by default | ✅ | △ | △ | △ |
| SSR-safe | ✅ | ❌ | △ | ❌ |
| Typed native events | ✅ | ❌ | ❌ | ❌ |
| CSS variable theming | ✅ | △ | △ | ❌ |
SeoSelect is not “good for a Web Component”.
It’s simply better for long-term products.
SeoToast: A Universal Toast Engine
Toast notifications shouldn’t require a framework.
They should just work.
SeoToast is designed to be:
- Small
- Predictable
- Accessible
- SSR-safe
- Framework-independent
Key Features
- Multiple types, positions, and animations
- Duplicate message grouping
- Progress bar with hover pause
- ARIA & keyboard accessibility
- ~10KB gzipped
- Optional wrappers for major frameworks
Comparison: SeoToast vs Popular Toast Libraries
| Feature | SeoToast | react-toastify | sonner | notistack |
|---|---|---|---|---|
| Framework-agnostic | ✅ | ❌ | ❌ | ❌ |
| Vanilla JS support | ✅ | ❌ | ❌ | ❌ |
| SSR-safe | ✅ | ❌ | △ | △ |
| Duplicate grouping | ✅ | ❌ | ❌ | ❌ |
| Zero dependencies | ✅ | ❌ | ❌ | ❌ |
| Accessibility | ✅ | △ | △ | △ |
Why This Approach Matters
Frameworks come and go.
Your UI behavior should not.
With Web Components:
- One UI engine
- Every framework
- Same UX
- Same events
- Same types
- Same accessibility guarantees
This isn’t about rejecting frameworks.
It’s about refusing to let them own your UI logic.
This Is Not an Experiment
I’m not “trying” Web Components.
I’m committing to them.
Because UI primitives should be:
- Stable
- Reusable
- Portable
- Boring (in the best way)
If this direction resonates with you, feel free to explore:
- SeoSelect → https://www.npmjs.com/package/seo-select
- SeoToast → https://www.npmjs.com/package/seo-toast
Feedback, criticism, and real-world usage stories are more than welcome.
Let’s build UI that outlives frameworks.
Top comments (0)