🚨 Shai-Hulud Strikes Again:834 Packages Compromised.Technical Analysis β†’
Socket
Book a DemoInstallSign in
Socket

@usex/rule-engine-builder

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@usex/rule-engine-builder

Visual rule construction toolkit for React applications. Drag, drop, and compose complex business logic without writing JSON. Transform IF-THEN decisions into intuitive visual flows with real-time evaluation, undo/redo history, and TypeScript-powered inte

latest
Source
npmnpm
Version
0.0.3
Version published
Maintainers
1
Created
Source
Rule Engine Builder Logo

@usex/rule-engine-builder

🎨 Visual Rule Constructor for React Applications

npm version license downloads stars

Quick Start β€’ Components β€’ Examples β€’ Why Visual Builder?

Create complex business rules with an intuitive drag-and-drop interface. No more JSON wrestling - build rules visually and export to your rule engine.

// Instead of writing complex JSON...
const rule = {
  conditions: [
    {
      and: [
        { field: "$.user.tier", operator: "equals", value: "premium" },
        { field: "$.order.total", operator: "greater-than", value: 100 }
      ],
      result: { discount: 0.15, shipping: "free" }
    }
  ]
};

// Just drag, drop, and configure visually! 🎨
<RuleBuilder 
  onRuleChange={setRule}
  availableFields={fields}
  theme="dark"
/>

πŸš€ Why Visual Builder?

Intuitive Visual Interface

  • 🎨 Drag & Drop - Build rules by dragging components onto a canvas
  • 🌲 Tree Structure - Visual representation of complex nested logic
  • πŸ“¦ Component Palette - Pre-built operators, fields, and logic blocks
  • 🎯 Drop Zones - Smart targeting for precise rule construction

Developer-Friendly Experience

  • ⚑ Real-time Preview - See JSON output as you build
  • πŸ”„ Live Evaluation - Test rules instantly with sample data
  • πŸ“ˆ History Management - Undo/redo with 100-entry history
  • ⌨️ Keyboard Shortcuts - Professional keyboard navigation

Production-Ready Features

  • πŸ›‘οΈ TypeScript Native - Full type safety and IntelliSense support
  • 🎨 Theme System - Light/dark modes with full customization
  • β™Ώ Accessible - WCAG compliant with screen reader support
  • πŸ“± Responsive - Works on desktop, tablet, and mobile devices

Extensible & Customizable

  • πŸ”§ Custom Operators - Add your own business-specific operators
  • πŸŽ›οΈ Field Discovery - Auto-suggest fields from your data schema
  • 🌈 Custom Themes - Match your application's design system
  • πŸ“Š Export Options - JSON, TypeScript, or custom formats

🎬 Quick Start

npm install @usex/rule-engine-builder @usex/rule-engine react

Basic Usage

import React, { useState } from 'react';
import { RuleBuilder } from '@usex/rule-engine-builder';
import { RuleEngine } from '@usex/rule-engine';

function App() {
  const [rule, setRule] = useState(null);
  
  // Define available fields for your users
  const availableFields = [
    { name: '$.user.tier', type: 'string', label: 'User Tier' },
    { name: '$.user.age', type: 'number', label: 'User Age' },
    { name: '$.order.total', type: 'number', label: 'Order Total' },
    { name: '$.order.items', type: 'array', label: 'Order Items' }
  ];

  // Test data for live evaluation
  const testData = {
    user: { tier: 'premium', age: 28 },
    order: { total: 150, items: ['laptop', 'mouse'] }
  };

  return (
    <div className="app">
      <h1>Build Your Business Rules</h1>
      
      <RuleBuilder
        rule={rule}
        onRuleChange={setRule}
        availableFields={availableFields}
        testData={testData}
        theme="auto"
        showPreview={true}
        showHistory={true}
      />
      
      {rule && (
        <div className="rule-output">
          <h3>Generated Rule:</h3>
          <pre>{JSON.stringify(rule, null, 2)}</pre>
          
          <button onClick={() => testRule()}>
            Test Rule
          </button>
        </div>
      )}
    </div>
  );

  async function testRule() {
    if (!rule) return;
    
    const result = await RuleEngine.evaluate(rule, testData);
    console.log('Rule Result:', result);
  }
}

πŸ—οΈ Core Components

RuleBuilder (Main Component)

The primary visual rule construction interface.

<RuleBuilder
  rule={rule}                    // Current rule state
  onRuleChange={setRule}         // Callback when rule changes
  availableFields={fields}       // Available fields for selection
  testData={testData}           // Sample data for live testing
  theme="dark"                  // Theme: 'light' | 'dark' | 'auto'
  showPreview={true}            // Show JSON preview panel
  showHistory={true}            // Enable undo/redo functionality
  customOperators={operators}    // Custom business operators
  onValidationError={onError}   // Validation error callback
  className="my-rule-builder"   // Custom CSS classes
/>

RuleEvaluator

Real-time rule evaluation with visual feedback.

<RuleEvaluator
  rule={rule}
  testData={testData}
  engine={RuleEngine}
  onResult={handleResult}
  showSteps={true}              // Show evaluation steps
  highlightActive={true}        // Highlight active rule paths
/>

ModernConstraintEditor

Advanced constraint editing with intelligent suggestions.

<ModernConstraintEditor
  constraint={constraint}
  onConstraintChange={setConstraint}
  availableFields={fields}
  operators={operators}
  showFieldSuggestions={true}
  allowCustomFields={true}
/>

πŸ”§ Component Showcase

Building Blocks

The visual builder provides intuitive components for every rule element:

Logic Operators

  • AND - All conditions must be true
  • OR - Any condition must be true
  • NONE - No conditions must be true

Comparison Operators

  • Equals (=) - Exact value matching
  • Greater Than (>) - Numeric comparison
  • Contains - Array/string inclusion
  • Matches - Regular expression patterns

Field Selectors

  • JSONPath Fields - $.user.profile.name
  • Nested Properties - Deep object navigation
  • Array Elements - $.items[0].price
  • Custom Fields - User-defined properties

Value Inputs

  • Static Values - Fixed strings, numbers, booleans
  • Dynamic References - $.other.field
  • Arrays - Multiple value selection
  • Date/Time - Calendar and time pickers

🎯 Real-World Examples

E-commerce Discount Builder

function DiscountRuleBuilder() {
  const [discountRule, setDiscountRule] = useState(null);
  
  const ecommerceFields = [
    { name: '$.customer.tier', type: 'string', label: 'Customer Tier', 
      options: ['bronze', 'silver', 'gold', 'platinum'] },
    { name: '$.cart.total', type: 'number', label: 'Cart Total' },
    { name: '$.cart.itemCount', type: 'number', label: 'Number of Items' },
    { name: '$.customer.isFirstOrder', type: 'boolean', label: 'First Order' },
    { name: '$.promotions.active', type: 'array', label: 'Active Promotions' }
  ];

  const customOperators = [
    {
      name: 'is-weekend',
      label: 'Is Weekend',
      category: 'datetime',
      description: 'Check if current date is weekend'
    },
    {
      name: 'bulk-discount-eligible',
      label: 'Bulk Discount Eligible',
      category: 'business',
      description: 'Check if order qualifies for bulk pricing'
    }
  ];

  return (
    <div className="discount-builder">
      <h2>Discount Rule Builder</h2>
      
      <RuleBuilder
        rule={discountRule}
        onRuleChange={setDiscountRule}
        availableFields={ecommerceFields}
        customOperators={customOperators}
        theme="light"
        resultTemplate={{
          discount: 0,
          code: '',
          message: '',
          expires: null
        }}
      />
    </div>
  );
}

User Access Control Builder

function AccessControlBuilder() {
  const [accessRule, setAccessRule] = useState(null);
  
  const accessFields = [
    { name: '$.user.role', type: 'string', label: 'User Role' },
    { name: '$.user.department', type: 'string', label: 'Department' },
    { name: '$.user.clearanceLevel', type: 'number', label: 'Clearance Level' },
    { name: '$.resource.sensitivity', type: 'string', label: 'Resource Sensitivity' },
    { name: '$.session.duration', type: 'number', label: 'Session Duration' },
    { name: '$.time.currentHour', type: 'number', label: 'Current Hour' }
  ];

  return (
    <div className="access-builder">
      <h2>Access Control Rules</h2>
      
      <RuleBuilder
        rule={accessRule}
        onRuleChange={setAccessRule}
        availableFields={accessFields}
        theme="dark"
        showHistory={true}
        resultTemplate={{
          allowed: false,
          permissions: [],
          expires: null,
          reason: ''
        }}
      />
      
      <RuleEvaluator
        rule={accessRule}
        testData={sampleUserSession}
        showSteps={true}
        onResult={(result) => {
          console.log('Access Decision:', result);
        }}
      />
    </div>
  );
}

Form Validation Builder

function ValidationBuilder() {
  const [validationRules, setValidationRules] = useState([]);
  
  const formFields = [
    { name: 'email', type: 'string', label: 'Email Address' },
    { name: 'password', type: 'string', label: 'Password' },
    { name: 'confirmPassword', type: 'string', label: 'Confirm Password' },
    { name: 'age', type: 'number', label: 'Age' },
    { name: 'country', type: 'string', label: 'Country' },
    { name: 'acceptTerms', type: 'boolean', label: 'Accept Terms' }
  ];

  return (
    <div className="validation-builder">
      <h2>Form Validation Rules</h2>
      
      {validationRules.map((rule, index) => (
        <div key={index} className="validation-rule">
          <h3>Rule {index + 1}</h3>
          
          <RuleBuilder
            rule={rule}
            onRuleChange={(newRule) => {
              const updated = [...validationRules];
              updated[index] = newRule;
              setValidationRules(updated);
            }}
            availableFields={formFields}
            mode="validation"
            showPreview={false}
          />
        </div>
      ))}
      
      <button onClick={() => addValidationRule()}>
        Add Validation Rule
      </button>
    </div>
  );
}

🎨 Advanced Features

Custom Themes

const customTheme = {
  colors: {
    primary: '#6366f1',
    secondary: '#10b981',
    background: '#f8fafc',
    surface: '#ffffff',
    text: '#1f2937',
    border: '#e5e7eb'
  },
  spacing: {
    sm: '0.5rem',
    md: '1rem',
    lg: '1.5rem'
  },
  borderRadius: '0.75rem',
  shadows: {
    sm: '0 1px 2px rgba(0, 0, 0, 0.05)',
    md: '0 4px 6px rgba(0, 0, 0, 0.1)'
  }
};

<RuleBuilder
  rule={rule}
  onRuleChange={setRule}
  theme={customTheme}
  availableFields={fields}
/>

Field Discovery

// Auto-discover fields from your data schema
const fields = useFieldDiscovery(sampleData, {
  maxDepth: 3,
  includeArrays: true,
  typeInference: true
});

<RuleBuilder
  rule={rule}
  onRuleChange={setRule}
  availableFields={fields}
  allowFieldDiscovery={true}
  onFieldDiscovered={(field) => {
    console.log('New field discovered:', field);
  }}
/>

History Management

function RuleBuilderWithHistory() {
  const [rule, setRule] = useState(null);
  const { history, undo, redo, canUndo, canRedo } = useRuleHistory();

  return (
    <div>
      <div className="history-controls">
        <button 
          onClick={undo} 
          disabled={!canUndo}
          title="Undo (Ctrl+Z)"
        >
          β†Ά Undo
        </button>
        
        <button 
          onClick={redo} 
          disabled={!canRedo}
          title="Redo (Ctrl+Y)"
        >
          β†· Redo
        </button>
        
        <span className="history-count">
          Step {history.currentIndex + 1} of {history.entries.length}
        </span>
      </div>

      <RuleBuilder
        rule={rule}
        onRuleChange={setRule}
        showHistory={true}
        maxHistoryEntries={100}
      />
    </div>
  );
}

Keyboard Shortcuts

The builder supports professional keyboard navigation:

ShortcutAction
Ctrl+ZUndo last change
Ctrl+YRedo last undone change
Ctrl+DDuplicate selected component
DeleteRemove selected component
TabNavigate between components
EnterEdit selected component
EscapeCancel current operation
Ctrl+SExport rule (custom handler)

🏎️ Performance & Optimization

Virtual Scrolling

For large rule sets, the builder uses virtual scrolling:

<RuleBuilder
  rule={complexRule}
  onRuleChange={setRule}
  virtualScrolling={true}
  itemHeight={60}
  maxVisibleItems={50}
/>

Lazy Loading

Components are loaded on-demand for better performance:

const LazyRuleBuilder = lazy(() => import('@usex/rule-engine-builder'));

function App() {
  return (
    <Suspense fallback={<div>Loading rule builder...</div>}>
      <LazyRuleBuilder />
    </Suspense>
  );
}

Optimized Rendering

// Use memo for expensive field calculations
const availableFields = useMemo(() => 
  generateFieldsFromSchema(schema), [schema]
);

// Debounce rule changes to reduce re-renders
const debouncedOnChange = useMemo(
  () => debounce(setRule, 300),
  []
);

<RuleBuilder
  rule={rule}
  onRuleChange={debouncedOnChange}
  availableFields={availableFields}
  optimizeRendering={true}
/>

πŸŽ“ TypeScript Support

Full type safety for all components and props:

interface CustomField {
  name: string;
  type: 'string' | 'number' | 'boolean' | 'array' | 'object';
  label: string;
  description?: string;
  options?: string[];
  validation?: {
    required?: boolean;
    min?: number;
    max?: number;
    pattern?: string;
  };
}

interface CustomRule<T = any> {
  id: string;
  conditions: Condition<T>[];
  result?: T;
  metadata?: {
    name: string;
    description: string;
    created: Date;
    modified: Date;
  };
}

// Type-safe rule builder
const Builder = () => {
  const [rule, setRule] = useState<CustomRule<DiscountResult>>(null);
  
  return (
    <RuleBuilder<DiscountResult>
      rule={rule}
      onRuleChange={setRule}
      availableFields={typedFields}
      resultType="discount"
    />
  );
};

πŸ§ͺ Testing Components

import { render, screen, fireEvent } from '@testing-library/react';
import { RuleBuilder } from '@usex/rule-engine-builder';

describe('RuleBuilder', () => {
  const mockFields = [
    { name: 'age', type: 'number', label: 'Age' },
    { name: 'country', type: 'string', label: 'Country' }
  ];

  it('should render field palette', () => {
    render(
      <RuleBuilder
        availableFields={mockFields}
        onRuleChange={jest.fn()}
      />
    );
    
    expect(screen.getByText('Age')).toBeInTheDocument();
    expect(screen.getByText('Country')).toBeInTheDocument();
  });

  it('should handle drag and drop', () => {
    const onChange = jest.fn();
    
    render(
      <RuleBuilder
        availableFields={mockFields}
        onRuleChange={onChange}
      />
    );
    
    const ageField = screen.getByText('Age');
    const dropZone = screen.getByTestId('drop-zone');
    
    fireEvent.dragStart(ageField);
    fireEvent.drop(dropZone);
    
    expect(onChange).toHaveBeenCalledWith(
      expect.objectContaining({
        conditions: expect.arrayContaining([
          expect.objectContaining({
            field: 'age'
          })
        ])
      })
    );
  });
});

πŸ“š Documentation & Resources

🀝 Contributing

We welcome contributions! Whether it's:

  • πŸ› Bug reports and fixes
  • ✨ New components or features
  • πŸ“– Documentation improvements
  • 🎨 Theme contributions

See our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/ali-master/rule-engine.git
cd rule-engine/packages/builder

# Install dependencies
pnpm install

# Start development server
pnpm dev

# Run tests
pnpm test

# Build for production
pnpm build

πŸ†š Why Choose This Builder?

Feature@usex/rule-engine-builderReact QueryBuilderReact Awesome Query Builder
TypeScript Nativeβœ…βš οΈ Partial⚠️ Partial
Drag & Dropβœ…βŒβœ…
Real-time Evaluationβœ…βŒβŒ
History/Undoβœ…βŒβŒ
Custom Themesβœ…βš οΈ Limitedβœ…
Mobile Responsiveβœ…βš οΈ Partial❌
JSONPath Supportβœ…βŒβŒ
Bundle Size45KB120KB180KB
Tree Visualizationβœ…βŒβœ…
Keyboard Shortcutsβœ…βŒβŒ

πŸ“„ License

MIT Β© Ali Torki

Built with ❀️ for modern React applications

⭐ Star us on GitHub β€’ πŸ› Report Issues β€’ πŸ’¬ Discussions

Keywords

react-rule-builder

FAQs

Package last updated on 10 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts