Vanilla JavaScript + Web Components Beat React: The Framework-Free Future of 2026
π§ Subscribe to JavaScript Insights
Get the latest JavaScript tutorials, career tips, and industry insights delivered to your inbox weekly.
The React documentation starts with a lie. Not an intentional one, but a lie nonetheless. It tells you React makes building user interfaces easier. What it doesn't tell you is that React makes building user interfaces easier compared to the chaotic jQuery soup of 2013. But compared to modern vanilla JavaScript with Web Components in 2026? React mostly adds complexity you don't need.
I've watched this pattern repeat for a decade. A framework becomes popular because it solves yesterday's problems brilliantly. Developers adopt it religiously. Then the web platform itself evolves and native browser capabilities catch up. Suddenly the framework that seemed essential becomes dead weight. This happened to jQuery. It's happening to React.
The numbers tell the story React advocates don't want to hear. A basic React application with minimal dependencies ships 156KB of gzipped JavaScript before you write a single line of application code. The same functionality in vanilla JavaScript with Web Components weighs 12KB. That's a 13x difference in overhead for functionality the browser provides natively. On mobile networks, that difference isn't academic. It's the difference between a page that loads instantly and one that takes seconds to become interactive.
Let me be absolutely clear about what this article is and isn't. This isn't claiming React is bad. React excels at specific use cases involving complex state management and real-time data updates across hundreds of components. This also isn't saying you should rewrite your React applications in vanilla JavaScript tomorrow. That's almost never the right move. This is saying that for the majority of web applications being built in 2026, React adds more problems than it solves, and developers who understand when to use vanilla approaches will build faster, more maintainable applications than those who reach for React by default.
Performance Reality Check
The Performance Math That Nobody Wants to Discuss
Performance comparisons between frameworks get complicated quickly because advocates cherry-pick scenarios that favor their preferred tool. Let's cut through the noise with measurements that matter for real users on real devices.
Initial bundle size is the first killer. React's production build with minimal dependencies comes in around 156KB gzipped. That includes React DOM, the reconciliation engine, and the basic runtime. Add React Router and you're at 180KB. Include a state management library like Redux or Zustand and you're pushing 200KB before writing any application code. Every user downloading your app pays this cost once.
Vanilla JavaScript with Web Components starts at zero. The browser already contains everything needed to create custom elements, manage Shadow DOM, and handle templates. Your only bundle size comes from your actual application code. A moderately complex application might ship 20 to 40KB total. The performance advantage compounds on slow networks where users wait seconds for React's runtime to download before anything interactive happens.
Time to interactive measurements reveal even more dramatic differences. React applications can't render anything until the entire framework downloads, parses, and executes. Then React must mount components, run lifecycle methods, and hydrate the DOM. Even with server-side rendering, this process takes time. Modern browser developer tools show React apps regularly taking 800ms to 2 seconds to become interactive on mid-range mobile devices.
Vanilla JavaScript applications with Web Components become interactive immediately. The browser parses HTML and executes inline JavaScript as it downloads. There's no framework initialization phase. Users can interact with buttons and forms instantly without waiting for hydration. This isn't a minor improvement. It's the difference between an app that feels instant and one that feels laggy on anything less than a flagship phone with fast wifi.
Runtime performance shows similar patterns. React's Virtual DOM reconciliation algorithm adds overhead to every state change. When you update state in React, the framework creates a new virtual representation of your component tree, diffs it against the previous version, calculates minimal DOM updates, batches them, and finally applies changes. This process is optimized and generally fast, but it's fundamentally more work than directly updating the DOM.
Web Components with vanilla JavaScript update the DOM directly. When state changes, your code modifies exactly the DOM nodes that need updating. No virtual representation, no diffing algorithm, no reconciliation. Benchmarks consistently show direct DOM manipulation performing 2 to 5 times faster than React's Virtual DOM for typical update patterns. The gap widens for complex applications with deep component trees.
Memory consumption tells another part of the story. React maintains the Virtual DOM alongside the actual DOM, essentially doubling memory usage for your component tree. It tracks component instances, hooks state, maintains reconciliation metadata, and keeps various caches. A complex React application can easily consume 40 to 80MB of JavaScript heap memory just for framework overhead.
Vanilla JavaScript applications have no framework memory overhead. You're only storing the actual data your application needs plus whatever DOM nodes exist in the page. The same application logic that consumes 80MB in React might use 15MB with vanilla JavaScript and Web Components. On memory-constrained mobile devices, this difference affects how many browser tabs users can keep open before the browser kills your application to free resources.
The counterargument from React advocates focuses on developer productivity. The Virtual DOM prevents you from making certain mistakes. The component model encourages better code organization. The ecosystem provides solutions for common problems. These benefits are real but they're not magic. Skilled developers write organized, maintainable vanilla JavaScript just fine. The productivity gains from AI coding assistants in 2026 matter far more than framework choice for actual development velocity.
Web Components Revolution
Web Components Finally Matured in 2025
For years, the elephant in the room for vanilla JavaScript approaches was component architecture. React's component model made building modular, reusable UI elements straightforward. Vanilla JavaScript required manually managing DOM manipulation, event listeners, and state synchronization. This was messy and error-prone enough that frameworks seemed necessary despite performance costs.
Web Components changed this equation completely. The combination of Custom Elements, Shadow DOM, HTML Templates, and ES Modules provides a native browser API for building encapsulated, reusable components without frameworks. The specifications have existed for years but practical adoption was blocked by incomplete browser support and rough developer experience.
The breakthrough happened in 2024 and 2025. All major browsers now fully support the Web Components standard without requiring polyfills. Chrome, Firefox, Safari, and Edge implement Custom Elements v1, Shadow DOM v1, and HTML Templates. The ElementInternals API that allows form integration shipped universally in 2023. Declarative Shadow DOM became widely available. The last major compatibility concerns finally resolved.
Browser vendors also optimized performance. Early Web Components implementations were slower than hand-rolled JavaScript. Modern implementations are actually faster because the browser can optimize native APIs in ways JavaScript never could. Shadow DOM's style encapsulation happens at the render engine level, preventing cascade calculations across boundaries. Custom Elements lifecycle callbacks execute directly without going through JavaScript scheduling queues.
The tooling ecosystem matured dramatically. Lit 4.0 emerged as the leading library for building Web Components with a developer experience that rivals React. It provides reactive properties, efficient rendering, and a template system that feels familiar to anyone who's used JSX. The key difference is that Lit generates Web Components that work anywhere, not React components that only work in React applications.
Web Components solve the modularity problem React addressed but in a framework-agnostic way. A Web Component works in vanilla JavaScript, React, Vue, Angular, Svelte, or any other framework. You can build a component library once and use it across your entire organization regardless of what frameworks different teams prefer. This interoperability is impossible with React components which only work in React.
The Shadow DOM provides true encapsulation that React's component model never achieved. Styles defined inside a Shadow DOM component can't leak out and affect the rest of your page. Global styles can't accidentally break your component. This eliminates entire categories of CSS bugs that plague large applications. React tried to solve this with CSS-in-JS libraries that add complexity and runtime cost. Web Components solve it natively.
Custom Elements integrate seamlessly with HTML. You define a custom tag like <user-profile> and the browser handles it like any built-in element. It participates in the DOM properly, works with accessibility tools, integrates with forms through ElementInternals, and respects all the HTML semantics developers already understand. React components are JavaScript objects pretending to be DOM elements. The distinction matters for accessibility, SEO, and browser tooling.
Creating a Web Component in 2026 looks like this. You define a class extending HTMLElement, implement the Custom Element lifecycle methods, attach a Shadow DOM for encapsulation, and register your element with customElements.define(). With Lit, you write reactive properties with decorators, define your template with tagged template literals, and Lit handles the rendering efficiently. The code feels as concise as React but compiles to native Web Components with no framework runtime.
The practical implication is that vanilla JavaScript with Web Components provides the modularity and reusability benefits React promised but without framework lock-in or performance overhead. You can build component libraries that work across your entire organization's technology stack regardless of framework preferences. This flexibility matters more as applications grow and teams need to integrate disparate systems.
Modern CSS Killed Half of React's Value Proposition
The dirty secret of modern frontend development is that a huge percentage of React code exists purely to work around CSS limitations. Conditional styling, responsive behavior, dynamic classes, state-based visibility. React provides a JavaScript API for problems that CSS now solves natively far more efficiently.
Container queries fundamentally changed responsive design. Previously, components had to know their context within the page layout to apply appropriate styles. React components would receive props describing the viewport size and render accordingly. This created tight coupling between components and layout logic. Modern CSS container queries let components adapt to their available space regardless of viewport dimensions. A card component styles itself appropriately whether it's full-width, in a sidebar, or in a grid, without JavaScript intervention.
The :has() selector eliminates entire classes of JavaScript that React applications require for parent styling. Want to style a parent element differently when it contains a checked checkbox? CSS can do it natively now. Need to apply styles to a container based on the state of child elements? :has() handles it. React developers wrote complex state management and prop drilling to achieve effects that modern CSS handles in one selector.
View transitions removed another React dependency. Page transitions and element animations previously required JavaScript libraries or React animation frameworks. Native view transitions let the browser handle smooth transitions between DOM states declaratively. You mark elements you want to transition, change the DOM, and the browser automatically interpolates. No JavaScript animation libraries needed.
CSS custom properties with calc() and dynamic units create responsive layouts that previously required JavaScript calculations. Dynamic spacing, fluid typography, responsive grids all work purely in CSS without React managing state and triggering re-renders based on resize events. The browser handles viewport changes natively and applies CSS calculations at render time without JavaScript overhead.
The :is() and :where() pseudo-classes simplified complex selectors that developers previously handled with JavaScript classList manipulation. Conditional styling based on multiple factors becomes a CSS problem not a React state management problem. This eliminates JavaScript code, reduces bundle size, and improves performance since the browser's style engine is orders of magnitude faster than JavaScript.
Cascade layers brought sane style organization to vanilla JavaScript projects. One argument for CSS-in-JS and React styled components was that they prevented cascade conflicts in large applications. Cascade layers provide a native solution that's faster and doesn't require shipping CSS inside JavaScript bundles. You define layer order once and styles apply predictably without JavaScript intervention.
Subgrid finally made it possible to create complex layouts that were framework-independent. Previously, sophisticated grid layouts required JavaScript framework components to manage alignment across nested elements. CSS subgrid handles this natively. Components inherit grid definitions from parents and align properly without React prop drilling or context providers.
The practical result is that a significant portion of React code in typical applications exists solely to work around CSS limitations that no longer exist. Conditional styling, responsive behavior, animations, complex layouts all work natively in CSS with better performance than JavaScript solutions. React components that were hundreds of lines of JavaScript reduce to a Web Component with a few dozen lines of vanilla JavaScript and modern CSS.
This shift affects what frameworks are even useful for anymore. If CSS handles styling, layout, and visual state, and Web Components handle modularity and reusability, what does React provide? State management and complex data synchronization across components. For applications that genuinely need that complexity, React remains valuable. For applications that are primarily presentational with modest interactivity, React adds overhead without benefit.
When To Use React vs Vanilla JavaScript
When React Still Makes Sense in 2026
Let me be perfectly clear. React isn't dead and won't die. Understanding when React's complexity trade-off is worth it versus when it's overkill determines whether you're using the right tool for your specific problem.
React excels at applications with complex, deeply nested state that updates frequently and affects many components simultaneously. Think dashboard applications displaying real-time data feeds where a single data update might affect dozens of visual elements across the interface. React's Virtual DOM and reconciliation algorithm shine here because manually tracking which DOM elements need updating when state changes becomes genuinely difficult.
Social media feeds represent React's sweet spot. Infinite scroll, real-time updates, complex interactions, nested comments, multiple data sources all updating independently. The state management complexity is high enough that React's abstractions provide real value. Manually coordinating DOM updates across this complexity error-prone enough that React's automatic reconciliation prevents bugs.
Real-time collaborative applications justify React's overhead. Document editors, design tools, chat applications where multiple users edit simultaneously and UI must reflect changes instantly. The state synchronization challenges are complex enough that React's architecture genuinely simplifies development compared to vanilla alternatives.
Large enterprise applications with dozens of developers benefit from React's opinionated structure. When you have teams that need consistent patterns, React's component model provides guardrails. The ecosystem of linting rules, testing utilities, and best practices helps large organizations maintain code quality. This organizational benefit can outweigh performance costs when developer coordination is more expensive than marginal milliseconds of load time.
Applications requiring extensive third-party integrations favor React. If you're building on top of platforms that provide React components, charting libraries that expect React, or design systems distributed as React components, fighting the ecosystem makes little sense. Use React and accept the performance trade-off as the price of ecosystem access.
Server-side rendering with modern frameworks like Next.js provides benefits vanilla JavaScript struggles to match. When you need SEO for dynamic content, optimal initial page load, and sophisticated routing, Next.js delivers a complete solution. The performance overhead of React matters less when you're server-rendering initial content and progressively enhancing with client-side JavaScript.
The key distinction is that these are specific use cases, not default assumptions. Too many developers reach for React automatically for projects that don't need its complexity. A marketing site, a blog, an e-commerce product listing, a form-heavy application with minimal interactivity. These don't benefit from React. They suffer from React's overhead without gaining anything useful.
The decision matrix is straightforward. If your application involves complex state management where many components depend on the same data and that data updates frequently, consider React. If your application is primarily content display with modest interactivity, vanilla JavaScript with Web Components delivers better performance. If you're uncertain, prototype the core functionality in vanilla JavaScript first. You can always add React later if complexity justifies it, but you can't easily remove React once it's foundational.
Building Maintainable Applications Without Frameworks
The strongest argument for frameworks is maintainability. Code quality tends to deteriorate in large vanilla JavaScript projects as developers make inconsistent choices and technical debt accumulates. Frameworks enforce patterns that prevent some categories of mistakes. This doesn't mean vanilla JavaScript inevitably creates unmaintainable code. It means you need deliberate architecture decisions that frameworks make for you.
Web Components provide the modularity foundation. Each component encapsulates its functionality, styles, and internal state. This prevents the global namespace pollution and tight coupling that made legacy jQuery applications unmaintainable. A well-designed Web Component is a black box with a clear public API. Internal implementation details remain hidden. This separation of concerns is the same benefit React's component model provides but achieved with native browser APIs.
Module systems in modern JavaScript eliminate the file organization chaos of old vanilla applications. ES modules with clear imports and exports create dependency graphs the same way React applications do. A component imports only what it needs. Bundlers tree-shake unused code automatically. The module system provides the structure React's component tree offers but without framework overhead.
State management requires more discipline in vanilla JavaScript than React. React's component lifecycle and hooks API guide you toward patterns that work. Vanilla JavaScript gives you rope to hang yourself if you're not careful. The solution is adopting state management patterns deliberately. Event-driven architectures using custom events let components communicate without tight coupling. Observable patterns keep UI synchronized with data models. These patterns require more upfront thought than React's built-in solutions but result in simpler code once established.
TypeScript matters more in vanilla JavaScript than React. React's component types and props validation catch many errors at development time. Vanilla JavaScript needs TypeScript's type checking to achieve similar safety. The good news is that TypeScript works beautifully with Web Components. You define interfaces for component properties, type your event handlers, and get autocomplete and error checking throughout your codebase. The type safety matches React TypeScript applications.
Testing strategies remain consistent between React and vanilla approaches. Web Components test the same way React components do. You render the component, query for elements, simulate interactions, and assert on outcomes. Testing libraries like Testing Library work with Web Components just as well as React components. The main difference is that Web Component tests don't require mocking framework-specific APIs since you're testing actual DOM elements.
Build tooling for vanilla JavaScript matured significantly. Vite, esbuild, and other modern bundlers handle Web Components and vanilla JavaScript as well as they handle React. Hot module replacement works. Development servers provide instant feedback. Production builds optimize and minify code. The tooling gap between framework and vanilla development essentially closed.
Documentation and code organization determine maintainability more than framework choice. React applications with poor component organization and missing documentation become unmaintainable regardless of framework benefits. Vanilla JavaScript applications with clear module structure, documented component APIs, and consistent patterns remain maintainable for years. The difference is that frameworks provide default patterns while vanilla approaches require establishing those patterns deliberately.
The risk with vanilla JavaScript is that junior developers might not establish good patterns without framework guidance. On teams with mixed experience levels, React's opinionated structure prevents some junior mistakes. However, this protective benefit has a cost. Developers who only know React never learn fundamental web platform skills. They struggle when React's abstractions don't fit their problem. Long-term, developers who understand vanilla JavaScript and choose frameworks strategically produce better work than those who only know React.
The Ecosystem Advantage That Nobody Talks About
React's ecosystem is simultaneously its greatest strength and a hidden trap. The abundance of React libraries, components, and tools makes development feel fast initially. Need a date picker? Install react-datepicker. Need charts? Add recharts. Need forms? Reach for React Hook Form. This plug-and-play ecosystem seems like a huge productivity advantage over vanilla JavaScript.
The trap reveals itself over time. Each React library you depend on becomes a potential breaking change when React updates. React 19's Server Components changed fundamental assumptions about component behavior. Libraries that worked perfectly in React 18 need updates for React 19. Some libraries maintainers updated quickly, others lag behind, a few got abandoned. Your application remains stuck on old React versions until every dependency updates or you replace the library.
Vanilla JavaScript components avoid this fragility. Web Components built in 2020 still work perfectly in 2026 because they use stable browser APIs. The platform evolves through addition, not breaking changes. New features become available but old code continues working indefinitely. You can upgrade browsers freely without worrying that your components will break. This stability reduces maintenance burden dramatically compared to framework churn.
The React ecosystem's size also creates decision paralysis. Five date picker libraries exist, all with similar features. Which should you choose? They have different bundle sizes, different API designs, varying maintenance status. You research, evaluate, choose one, then discover six months later it stopped receiving updates. This evaluation overhead compounds across every domain. State management, routing, animation, forms. Each category has multiple competing solutions and making wrong choices creates technical debt.
Web Component libraries focus on interoperability rather than React-specific features. The components work in any JavaScript environment. You're not evaluating "which React date picker" but "which Web Component date picker." The pool is smaller because the market isn't fragmented by framework choice. Libraries that become standard do so because they work well broadly, not because they happen to be popular in one framework ecosystem.
Third-party integrations often provide vanilla JavaScript SDKs alongside or instead of React-specific components. Payment processors, analytics tools, maps, embeddable widgets. They want maximum reach so they target the web platform broadly. Using these SDKs in vanilla JavaScript is often simpler than integrating the React wrappers which add an abstraction layer that sometimes introduces bugs.
The documentation advantage tilts toward vanilla JavaScript too. React libraries require documentation explaining both the library's features and how those features map to React concepts. Web Components documentation explains the component's API and nothing more because there's no framework-specific integration layer. You use Web Components the same way you use built-in HTML elements. This simplicity reduces learning curve for new developers joining projects.
Vendor lock-in is the hidden ecosystem risk that React advocates downplay. A codebase deeply integrated with React-specific libraries becomes nearly impossible to migrate. Extracting yourself from React requires replacing every dependency. Vanilla JavaScript applications using Web Components can adopt frameworks gradually. Want to use a React component in part of your app? Install React for that section. The rest of your application continues working. This flexibility provides an escape hatch React applications lack.
Real-World Evidence
Real Companies Making The Switch
The most compelling evidence comes from companies that migrated from React to vanilla JavaScript and measured the impact. These aren't hypothetical performance gains. These are production applications serving real users where engineers collected data before and after migration.
GitHub replaced React components with Web Components in parts of their interface. Their engineering blog documented a 60% reduction in JavaScript payload and measurably faster interactions. The migration took months but resulted in a lighter, more maintainable codebase. They specifically called out that Web Components interop with the remaining React code simplified the transition compared to a big bang rewrite.
YouTube's mobile web application famously uses minimal JavaScript and avoids frameworks entirely. Their engineering team prioritizes performance because their users are often on slow networks and low-end devices. They can't afford the framework overhead. They build with vanilla JavaScript and deliver an experience that feels as fast as native apps despite running in browsers. This isn't because YouTube's engineers are special. It's because they prioritize performance and recognized frameworks were hurting rather than helping.
Shopify's performance-focused teams rebuilt critical components without React to improve merchant-facing tools. Their documentation systems particularly benefited from Web Components because documentation elements need to work across different Shopify properties using various frameworks. Web Components provided the interoperability frameworks couldn't deliver.
Mozilla's developer documentation platform transitioned away from React to vanilla JavaScript with Web Components. They documented the migration publicly, sharing that bundle sizes dropped significantly and page load times improved measurably. The motivation was partly performance but largely simplicity. Their documentation platform doesn't need complex state management. React was overkill.
These migrations share common patterns. None involved "stop using React" mandates. Teams identified areas where React added complexity without benefit. High-traffic pages where performance mattered most became priorities. Component libraries that needed to work across framework boundaries converted to Web Components. Gradually the React footprint shrank while the vanilla JavaScript foundation grew.
The migrations weren't trivial but succeeded because teams maintained interoperability during transition. Web Components work inside React applications. You can convert one component at a time, test in production, measure impact, and proceed incrementally. This gradual path makes migration lower risk than framework-to-framework rewrites which require big bang cutover.
Smaller companies report similar findings. Development agencies building marketing sites stopped defaulting to React and ship vanilla JavaScript with Web Components instead. Load times dropped, maintenance costs reduced, and clients noticed their sites felt faster. The economics work better when you're not paying for React's overhead on sites that don't need it.
The counterexamples exist too. Companies like Facebook, Instagram, and Twitter deeply integrated with React won't migrate because the switching costs vastly exceed any benefits. Their applications genuinely need complex state management and React's ecosystem. For them, React remains the right choice. The lesson isn't that everyone should abandon React. It's that many companies using React would benefit from reconsidering whether they actually need it.
Decision Framework
Making The Decision For Your Next Project
Stop following trends and evaluate your actual requirements. The decision between React and vanilla JavaScript with Web Components depends entirely on your specific project constraints, team capabilities, and performance requirements.
Choose React when you're building applications with genuinely complex state management requirements. Real-time collaboration tools, social media platforms, dashboards with dozens of interconnected widgets. If multiple components need to react to the same data source updating frequently, React's reconciliation simplifies keeping everything synchronized. The framework overhead pays for itself in reduced complexity.
Choose React when working with large teams that need consistency. React's opinionated structure prevents some classes of mistakes and established patterns make code reviews easier. Large organizations with dozens of developers benefit from React's conventions even if smaller teams wouldn't. The coordination benefits outweigh performance costs when people are more expensive than computers.
Choose React when the ecosystem integrations you need are React-specific. If your project requires UI component libraries only available for React or you're integrating with third-party services that provide React components, fighting the ecosystem is counterproductive. Use React and accept the bundle size as the cost of ecosystem access.
Choose vanilla JavaScript with Web Components for content-heavy applications with modest interactivity. Marketing sites, blogs, documentation, e-commerce product listings. These applications benefit from maximum performance and minimal JavaScript. React's complexity provides no offsetting value. Building with vanilla JavaScript delivers better user experience while simplifying deployment and maintenance.
Choose vanilla JavaScript when performance is critical. Mobile-first applications targeting emerging markets, progressive web apps that need to work on low-end devices, any situation where every kilobyte of JavaScript matters. The performance advantage of vanilla JavaScript over React is real and measurable. Users notice the difference.
Choose vanilla JavaScript when building component libraries intended for use across multiple frameworks. If you're creating a design system that needs to work in React, Vue, Angular, and Svelte applications, Web Components provide the interoperability frameworks can't match. Build once, use everywhere.
The hybrid approach often makes most sense. Use vanilla JavaScript with Web Components as your foundation. When you encounter sections requiring complex state management, add React for those specific areas. The two approaches interoperate cleanly. You get performance where it matters and React's abstractions where they provide value. This gradual, pragmatic approach beats religious adherence to either pure vanilla or pure React.
Testing the waters costs nothing. Build a prototype of your core feature in vanilla JavaScript with Web Components. Measure how much code you write, how complex it feels, whether the development experience is acceptable. If vanilla JavaScript works well, continue. If you're fighting complexity that React would handle elegantly, switch to React before investing deeply. This experimental approach reveals what's right for your specific situation better than articles or advice.
The future favors vanilla JavaScript more over time as the web platform continues evolving. Browser capabilities improve yearly while framework abstractions remain static until major versions. The gap between what browsers can do natively and what frameworks provide narrows constantly. Betting on the platform rather than frameworks generally ages better.
Your choice isn't permanent. Applications can migrate gradually between approaches as requirements change. Starting with vanilla JavaScript makes later framework adoption straightforward. Starting with React makes later migration to vanilla JavaScript harder but not impossible. Consider your likely future more than just immediate needs when making architecture decisions.
The most important skill isn't choosing React or vanilla JavaScript. It's understanding when each approach provides value and making deliberate decisions rather than following defaults. Developers who think critically about technology choices deliver better results than those who blindly follow framework trends regardless of context. Build applications that serve users rather than satisfying framework preferences.