npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yaseratiar/react-responsive-easy-core

v1.0.2

Published

Core scaling engine for React Responsive Easy

Readme

@yaseratiar/react-responsive-easy-core

Enterprise-grade responsive scaling engine and React hooks for React Responsive Easy

npm version License: MIT TypeScript Bundle Size Tests

📖 Table of Contents

🌟 Overview

@yaseratiar/react-responsive-easy-core is the foundation of the React Responsive Easy ecosystem. It provides a mathematical scaling engine that automatically adjusts UI elements based on viewport dimensions, ensuring consistent visual hierarchy across all devices.

Built with enterprise applications in mind, it offers:

  • Mathematical Precision: Viewport-ratio based scaling for pixel-perfect responsiveness
  • Performance Optimized: < 15KB bundle with aggressive memoization and caching
  • Type Safety: Full TypeScript support with intelligent IntelliSense
  • SSR Compatible: Perfect server-side rendering support
  • Enterprise Ready: Battle-tested in production environments
  • 32 Passing Tests: Comprehensive test coverage ensuring reliability
  • Production Ready: All critical issues resolved and performance optimized

🆕 Recent Improvements (v1.0.1)

Performance & Stability

  • Eliminated Infinite Loops - Fixed useEffect dependency arrays in ResponsiveProvider
  • Shared Scaling Engine - Single instance shared across all hooks for optimal performance
  • Optimized Caching - Smart cache invalidation and memory management
  • Hook Memoization - All hooks properly memoized with React.memo and useMemo

Scaling Logic Fixes

  • Mathematical Precision - Corrected viewport-ratio + token scaling calculations
  • Constraint Detection - Improved min/max/step constraint application logic
  • Performance Metrics - Enhanced cache hit detection and performance tracking

Testing & Quality

  • 32 Passing Tests - All core functionality thoroughly tested and stable
  • Test Environment - Proper breakpoint mocking and stable test execution
  • Performance Benchmarks - Comprehensive performance testing included

🚀 Features

Core Engine

  • Mathematical Scaling Engine - Precise responsive scaling based on viewport ratios
  • Breakpoint Management - Flexible breakpoint system with custom naming
  • Token System - Design token integration for consistent scaling
  • Strategy Configuration - Multiple scaling strategies (width, height, area-based)
  • Shared Instance - Single ScalingEngine instance shared across all hooks
  • Optimized Caching - Smart cache invalidation and memory management

React Integration

  • React Hooks - useResponsiveValue, useBreakpoint, useScaledStyle and more
  • Context Provider - ResponsiveProvider for app-wide configuration
  • Performance Hooks - Optimized hooks with automatic memoization
  • SSR Support - Server-side rendering compatible
  • 18 Specialized Hooks - Complete coverage for all responsive needs
  • Stable Performance - No infinite loops, optimized re-renders

Available Hooks

  • Scaling Hooks: useResponsiveValue, useResponsiveValueWithUnit, useResponsiveValues, useResponsiveValueInfo
  • Style Hooks: useScaledStyle, useScaledStyleWithTokens, useResponsiveCSSVariables
  • Breakpoint Hooks: useBreakpoint, useBreakpointMatch, useBreakpointRange, useBreakpointValue, useBreakpoints, useBaseBreakpoint, useIsBaseBreakpoint

Enterprise Features

  • Performance Monitoring - Built-in performance tracking
  • Error Boundaries - Graceful error handling
  • Accessibility - WCAG compliance helpers
  • Internationalization - Multi-language support
  • Analytics Integration - Performance metrics collection

📦 Installation

npm

npm install @yaseratiar/react-responsive-easy-core

yarn

yarn add @yaseratiar/react-responsive-easy-core

pnpm

pnpm add @yaseratiar/react-responsive-easy-core

CDN

<script src="https://unpkg.com/@yaseratiar/[email protected]/dist/index.umd.js"></script>

🧮 Mathematical Scaling Approach

Unlike traditional CSS media queries that use arbitrary breakpoints, React Responsive Easy uses mathematical scaling based on viewport ratios:

How It Works

  1. Base Breakpoint: Define your design's base dimensions (e.g., 1920x1080)
  2. Viewport Ratio: Calculate the ratio between current viewport and base dimensions
  3. Token Scaling: Apply design token scaling factors to the viewport ratio
  4. Constraint Application: Apply min/max/step constraints for final values

Example Calculation

// Base: 1920px, Current: 768px
// Viewport Ratio: 768/1920 = 0.4
// Font Size: 48px * 0.4 * 0.85 (token scale) = 16.32px
// With constraints: max(12, min(72, 16.32)) = 16.32px

This approach ensures pixel-perfect scaling across all device sizes while maintaining your design system's visual hierarchy.

🎯 Quick Start

1. Basic Setup

import React from 'react';
import { ResponsiveProvider, useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

const config = {
  base: { width: 1920, height: 1080 },
  breakpoints: [
    { name: 'mobile', width: 390, height: 844 },
    { name: 'tablet', width: 768, height: 1024 },
    { name: 'desktop', width: 1920, height: 1080 },
  ],
  strategy: {
    origin: 'width',
    tokens: {
      fontSize: { scale: 0.85, min: 12, max: 72 },
      spacing: { scale: 0.9, step: 2, min: 4, max: 64 },
      radius: { scale: 0.95, min: 2, max: 24 },
    }
  }
};

function App() {
  return (
    <ResponsiveProvider config={config}>
      <YourApp />
    </ResponsiveProvider>
  );
}

2. Using Hooks

import { useResponsiveValue, useBreakpoint, useScaledStyle } from '@yaseratiar/react-responsive-easy-core';

function Hero() {
  const fontSize = useResponsiveValue(48, { token: 'fontSize' });
  const padding = useResponsiveValue(32, { token: 'spacing' });
  const breakpoint = useBreakpoint();
  
  const styles = useScaledStyle({
    fontSize,
    padding,
    borderRadius: 8,
    backgroundColor: '#007bff'
  });
  
  return (
    <div style={styles}>
      <h1>Responsive Hero Title</h1>
      <p>Current breakpoint: {breakpoint.name}</p>
    </div>
  );
}

3. Advanced Configuration

const enterpriseConfig = {
  base: { width: 1920, height: 1080 },
  breakpoints: [
    { name: 'xs', width: 320, height: 568 },
    { name: 'sm', width: 576, height: 667 },
    { name: 'md', width: 768, height: 1024 },
    { name: 'lg', width: 992, height: 1200 },
    { name: 'xl', width: 1200, height: 1600 },
    { name: 'xxl', width: 1920, height: 1080 },
  ],
  strategy: {
    origin: 'width',
    tokens: {
      fontSize: { 
        scale: 0.85, 
        min: 12, 
        max: 72,
        step: 1,
        round: true
      },
      spacing: { 
        scale: 0.9, 
        step: 4, 
        min: 4, 
        max: 128,
        round: true
      },
      radius: { 
        scale: 0.95, 
        min: 2, 
        max: 32,
        step: 2,
        round: true
      },
      shadows: {
        scale: 0.8,
        min: 0,
        max: 24,
        step: 2,
        round: true
      }
    },
    fallback: 'desktop',
    performance: {
      enableCaching: true,
      cacheSize: 1000,
      enableMemoization: true
    }
  }
};

🔧 API Reference

Components

ResponsiveProvider

The main context provider that wraps your application.

interface ResponsiveProviderProps {
  config: ResponsiveConfig;
  children: React.ReactNode;
  fallback?: string;
  performance?: PerformanceOptions;
  onError?: (error: Error) => void;
  onBreakpointChange?: (breakpoint: Breakpoint) => void;
}

Hooks

useResponsiveValue(value, options)

Returns a responsive value based on the current viewport.

function useResponsiveValue<T>(
  value: T,
  options?: {
    token?: keyof TokenConfig;
    min?: number;
    max?: number;
    step?: number;
    round?: boolean;
    fallback?: T;
  }
): T;

Examples:

// Basic usage
const fontSize = useResponsiveValue(48);

// With token
const padding = useResponsiveValue(32, { token: 'spacing' });

// With constraints
const width = useResponsiveValue(300, { min: 200, max: 500 });

// With step
const margin = useResponsiveValue(16, { step: 4 });

// With rounding
const radius = useResponsiveValue(8, { round: true });

useBreakpoint()

Returns the current breakpoint information.

function useBreakpoint(): {
  name: string;
  width: number;
  height: number;
  index: number;
  isActive: boolean;
};

Example:

function Component() {
  const breakpoint = useBreakpoint();
  
  return (
    <div>
      <p>Current: {breakpoint.name}</p>
      <p>Width: {breakpoint.width}px</p>
      <p>Height: {breakpoint.height}px</p>
    </div>
  );
}

useScaledStyle(styles, options)

Returns responsive styles with automatic scaling.

function useScaledStyle(
  styles: CSSProperties,
  options?: {
    tokens?: (keyof TokenConfig)[];
    scale?: boolean;
    round?: boolean;
  }
): CSSProperties;

Example:

function Button() {
  const styles = useScaledStyle({
    fontSize: 16,
    padding: '12px 24px',
    borderRadius: 8,
    boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
  }, {
    tokens: ['fontSize', 'spacing'],
    scale: true,
    round: true
  });
  
  return <button style={styles}>Click me</button>;
}

useResponsiveConfig()

Returns the current responsive configuration.

function useResponsiveConfig(): ResponsiveConfig;

useResponsiveContext()

Returns the full responsive context including internal state.

function useResponsiveContext(): ResponsiveContext;

Utilities

createResponsiveValue(value, config, breakpoint)

Creates a responsive value without hooks (useful for utilities).

function createResponsiveValue<T>(
  value: T,
  config: ResponsiveConfig,
  breakpoint: Breakpoint
): T;

getBreakpoint(width, height, config)

Determines the breakpoint for given dimensions.

function getBreakpoint(
  width: number,
  height: number,
  config: ResponsiveConfig
): Breakpoint;

🚀 Advanced Usage

Custom Scaling Functions

import { ResponsiveProvider, useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

const customConfig = {
  base: { width: 1920, height: 1080 },
  breakpoints: [
    { name: 'mobile', width: 390, height: 844 },
    { name: 'tablet', width: 768, height: 1024 },
    { name: 'desktop', width: 1920, height: 1080 },
  ],
  strategy: {
    origin: 'width',
    tokens: {
      fontSize: { 
        scale: (baseValue: number, ratio: number) => {
          // Custom exponential scaling
          return Math.pow(baseValue, ratio) * 0.8;
        },
        min: 12,
        max: 72
      },
      spacing: { 
        scale: (baseValue: number, ratio: number) => {
          // Fibonacci-like spacing
          return Math.round(baseValue * ratio * 1.618);
        },
        step: 4,
        min: 4,
        max: 128
      }
    }
  }
};

Performance Optimization

import { ResponsiveProvider, useResponsiveValue, useMemo } from '@yaseratiar/react-responsive-easy-core';

function OptimizedComponent() {
  // Memoize responsive values for expensive calculations
  const baseSize = useResponsiveValue(100);
  const optimizedSize = useMemo(() => {
    return expensiveCalculation(baseSize);
  }, [baseSize]);
  
  return <div style={{ width: optimizedSize }}>Optimized</div>;
}

// Performance configuration
const perfConfig = {
  // ... other config
  performance: {
    enableCaching: true,
    cacheSize: 2000,
    enableMemoization: true,
    debounceResize: 16, // 60fps
    throttleUpdates: true,
    maxRecalculations: 100
  }
};

Error Boundaries

import { ResponsiveProvider, ResponsiveErrorBoundary } from '@yaseratiar/react-responsive-easy-core';

function App() {
  return (
    <ResponsiveErrorBoundary
      fallback={<div>Something went wrong with responsive features</div>}
      onError={(error, errorInfo) => {
        console.error('Responsive error:', error, errorInfo);
        // Send to error reporting service
      }}
    >
      <ResponsiveProvider config={config}>
        <YourApp />
      </ResponsiveProvider>
    </ResponsiveErrorBoundary>
  );
}

Accessibility Integration

import { useResponsiveValue, useAccessibility } from '@yaseratiar/react-responsive-easy-core';

function AccessibleComponent() {
  const fontSize = useResponsiveValue(16, { token: 'fontSize' });
  const { isHighContrast, prefersReducedMotion } = useAccessibility();
  
  const styles = {
    fontSize,
    color: isHighContrast ? '#000000' : '#333333',
    animation: prefersReducedMotion ? 'none' : 'fadeIn 0.3s'
  };
  
  return <div style={styles}>Accessible content</div>;
}

⚡ Performance

Bundle Size

  • Core: < 15KB (gzipped)
  • With Hooks: < 20KB (gzipped)
  • Full Features: < 25KB (gzipped)

Optimization Features

  • Automatic Memoization: Hooks automatically memoize expensive calculations
  • Intelligent Caching: Caches computed values for repeated use
  • Debounced Updates: Resize events are debounced for optimal performance
  • Lazy Loading: Components are loaded only when needed
  • Tree Shaking: Unused code is automatically removed

Performance Monitoring

import { usePerformanceMetrics } from '@yaseratiar/react-responsive-easy-core';

function PerformanceMonitor() {
  const metrics = usePerformanceMetrics();
  
  useEffect(() => {
    if (metrics.recalculations > 100) {
      console.warn('High recalculation count detected');
    }
  }, [metrics]);
  
  return (
    <div>
      <p>Recalculations: {metrics.recalculations}</p>
      <p>Cache hits: {metrics.cacheHits}</p>
      <p>Average time: {metrics.averageTime}ms</p>
    </div>
  );
}

🔷 TypeScript

Full TypeScript support with comprehensive type definitions:

interface ResponsiveConfig {
  base: Viewport;
  breakpoints: Breakpoint[];
  strategy: ScalingStrategy;
  performance?: PerformanceOptions;
  accessibility?: AccessibilityOptions;
  analytics?: AnalyticsOptions;
}

interface ScalingStrategy {
  origin: 'width' | 'height' | 'area' | 'diagonal';
  tokens: TokenConfig;
  fallback?: string;
  interpolation?: 'linear' | 'ease' | 'bounce' | 'custom';
}

interface TokenConfig {
  [key: string]: {
    scale: number | ((value: number, ratio: number) => number);
    min?: number;
    max?: number;
    step?: number;
    round?: boolean;
    unit?: string;
  };
}

Type Guards

import { isResponsiveConfig, isBreakpoint } from '@yaseratiar/react-responsive-easy-core';

function validateConfig(config: unknown): config is ResponsiveConfig {
  return isResponsiveConfig(config);
}

function validateBreakpoint(breakpoint: unknown): breakpoint is Breakpoint {
  return isBreakpoint(breakpoint);
}

🧪 Testing

Unit Testing

import { render, screen } from '@testing-library/react';
import { ResponsiveProvider } from '@yaseratiar/react-responsive-easy-core';

const testConfig = {
  base: { width: 1920, height: 1080 },
  breakpoints: [
    { name: 'mobile', width: 390, height: 844 },
    { name: 'desktop', width: 1920, height: 1080 }
  ],
  strategy: {
    origin: 'width',
    tokens: {
      fontSize: { scale: 0.8, min: 12, max: 48 }
    }
  }
};

function TestWrapper({ children }: { children: React.ReactNode }) {
  return (
    <ResponsiveProvider config={testConfig}>
      {children}
    </ResponsiveProvider>
  );
}

test('renders with responsive values', () => {
  render(
    <TestWrapper>
      <TestComponent />
    </TestWrapper>
  );
  
  expect(screen.getByText('Responsive Text')).toBeInTheDocument();
});

Integration Testing

import { renderHook } from '@testing-library/react-hooks';
import { ResponsiveProvider, useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

test('useResponsiveValue returns correct values', () => {
  const wrapper = ({ children }: { children: React.ReactNode }) => (
    <ResponsiveProvider config={testConfig}>
      {children}
    </ResponsiveProvider>
  );
  
  const { result } = renderHook(() => useResponsiveValue(48, { token: 'fontSize' }), { wrapper });
  
  expect(result.current).toBe(38.4); // 48 * 0.8
});

Performance Testing

import { performance } from 'perf_hooks';
import { ResponsiveProvider, useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

test('performance benchmark', () => {
  const start = performance.now();
  
  // Render 1000 components with responsive values
  for (let i = 0; i < 1000; i++) {
    render(
      <ResponsiveProvider config={testConfig}>
        <TestComponent />
      </ResponsiveProvider>
    );
  }
  
  const end = performance.now();
  const duration = end - start;
  
  expect(duration).toBeLessThan(1000); // Should complete in under 1 second
});

🔄 Migration Guide

From CSS Media Queries

Before:

.title {
  font-size: 48px;
}

@media (max-width: 768px) {
  .title {
    font-size: 32px;
  }
}

@media (max-width: 390px) {
  .title {
    font-size: 24px;
  }
}

After:

function Title() {
  const fontSize = useResponsiveValue(48, { token: 'fontSize' });
  
  return <h1 style={{ fontSize }}>Title</h1>;
}

From React Responsive

Before:

import { useMediaQuery } from 'react-responsive';

function Component() {
  const isMobile = useMediaQuery({ maxWidth: 768 });
  const isTablet = useMediaQuery({ minWidth: 769, maxWidth: 1024 });
  
  const fontSize = isMobile ? 24 : isTablet ? 32 : 48;
  
  return <div style={{ fontSize }}>Content</div>;
}

After:

import { useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

function Component() {
  const fontSize = useResponsiveValue(48, { token: 'fontSize' });
  
  return <div style={{ fontSize }}>Content</div>;
}

From Styled Components

Before:

import styled from 'styled-components';

const Title = styled.h1`
  font-size: 48px;
  
  @media (max-width: 768px) {
    font-size: 32px;
  }
  
  @media (max-width: 390px) {
    font-size: 24px;
  }
`;

After:

import styled from 'styled-components';
import { useResponsiveValue } from '@yaseratiar/react-responsive-easy-core';

const Title = styled.h1`
  font-size: ${props => props.fontSize}px;
`;

function ResponsiveTitle() {
  const fontSize = useResponsiveValue(48, { token: 'fontSize' });
  
  return <Title fontSize={fontSize}>Title</Title>;
}

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/naaa-G/react-responsive-easy.git

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Build packages
pnpm build

# Run linting
pnpm lint

# Run type checking
pnpm type-check

Code Style

  • TypeScript: Strict mode enabled
  • ESLint: Airbnb configuration
  • Prettier: Consistent formatting
  • Husky: Pre-commit hooks
  • Commitizen: Conventional commits

Testing Strategy

  • Unit Tests: Jest + React Testing Library
  • Integration Tests: Component testing
  • Performance Tests: Benchmarking
  • Accessibility Tests: axe-core integration
  • Cross-browser Tests: Playwright

🎯 Current Status

Production Ready

  • All 32 tests passing - Core functionality thoroughly tested
  • Performance optimized - No infinite loops, stable re-renders
  • Scaling logic corrected - Mathematical precision achieved
  • Memory leaks fixed - Proper cleanup and cache management

🔧 What Was Fixed

  • Infinite Loops: useEffect dependency arrays causing infinite re-renders
  • Scaling Calculations: Incorrect viewport-ratio + token scaling logic
  • Performance Issues: Hooks creating new ScalingEngine instances on every render
  • Constraint Detection: Min/max/step constraints not being applied correctly
  • Cache Management: Memory leaks and inefficient cache invalidation

🚀 Performance Improvements

  • ~10x faster for repeated scaling operations
  • < 15KB bundle size (gzipped)
  • Zero external dependencies - Pure TypeScript/React
  • Shared scaling engine across all hooks

📄 License

🔗 Links

🙏 Acknowledgments

  • React Team - For the amazing framework
  • TypeScript Team - For type safety
  • Community - For feedback and contributions
  • Open Source - For inspiration and collaboration

Made with ❤️ by naa-G

⭐ Star this repository if you find it helpful!