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

@gamesberry/karmyc-core

v1.0.0-beta22

Published

A flexible and powerful layout management system for React applications

Readme

Karmyc Core


npm version MIT License npm downloads TypeScript React

Table of Contents

Overview

Karmyc Core is a React library that provides a flexible layout management system using Zustand for state management. It allows you to create dynamic, resizable workspace areas that can be arranged in rows and columns, with support for multiple screens, undo/redo functionality, and a plugin system.

Demo

A comprehensive demo is available here showcasing Karmyc Core's key features.

Quick Start

1. Installation

# Using yarn (recommended)
yarn add @gamesberry/karmyc-core

# Using npm
npm install @gamesberry/karmyc-core

Dependencies

Karmyc Core requires the following peer dependencies:

  • react >= 19.0
  • react-dom >= 19.0

2. Basic Setup

// App.tsx
import { KarmycCoreProvider, useKarmyc, Karmyc, Tools } from '@gamesberry/karmyc-core';
import { AreaInitializer } from './AreaInitializer';

const App = () => {
  const karmycConfig = {
    plugins: [],
    validators: [],
    initialAreas: [
      { id: 'area-1', type: 'my-area', state: { initialData: 'default value' }, role: 'SELF' },
    ],
    keyboardShortcutsEnabled: true,
    resizableAreas: true,
    manageableAreas: true,
    multiScreen: true,
    allowStackMixedRoles: false,
    previewDuringDrag: false,
    builtInLayouts: [],
    initialLayout: 'default',
  };
  const config = useKarmyc(karmycConfig);

  return (
    <KarmycCoreProvider options={config}>
      <AreaInitializer />
      <Tools areaType="apptitle">
        <Tools areaType="app">
          <Karmyc />
        </Tools>
      </Tools>
    </KarmycCoreProvider>
  );
};

2b. Next.js / SSR usage

When using Next.js, wrap your app with KarmycNextWrapper to ensure safe client-side hydration:

// app/providers.tsx or pages/_app.tsx
import { KarmycNextWrapper, useKarmyc } from '@gamesberry/karmyc-core';

export default function Providers({ children }: { children: React.ReactNode }) {
  const config = useKarmyc({ initialAreas: [] });
  const isClient = typeof window !== 'undefined';
  return (
    <KarmycNextWrapper isClient={isClient} config={config}>
      {children}
    </KarmycNextWrapper>
  );
}

3. Area Initialization

// AreaInitializer.tsx
import { MyArea } from './areas/MyArea';

export const AreaInitializer = () => {
  return (
    <>
      <MyArea />
    </>
  );
};

4. Defining an Area Type

// areas/MyArea.tsx
import { useRegisterAreaType, AREA_ROLE } from '@gamesberry/karmyc-core';
import { MyAreaComponent } from './MyAreaComponent';
import { Icon } from 'lucide-react';

export const MyArea = () => {
  useRegisterAreaType(
    'my-area',
    MyAreaComponent,
    { initialData: 'default value' },
    {
      displayName: 'My Area',
      role: AREA_ROLE.LEAD,
      icon: Icon
    }
  );
  return null;
};

5. Area Component

// MyAreaComponent.tsx
import { AreaComponentProps } from '@gamesberry/karmyc-core';

interface MyAreaState {
  initialData: string;
}

export const MyAreaComponent: React.FC<AreaComponentProps<MyAreaState>> = ({
  id,
  state,
  type,
  viewport,
  raised
}) => {
  return (
    <div style={{ 
      width: viewport.width, 
      height: viewport.height, 
      left: viewport.left, 
      top: viewport.top 
    }}>
      <h2>My Area: {state.initialData}</h2>
    </div>
  );
};

Core Concepts

Screens, Spaces, Areas, and Layouts

  • Screen: A top-level container (main window or detached window) that contains areas and layout
  • Area: A rectangular region that renders a specific React component, organized within a screen
  • Layout: Tree structure of nested rows and columns defining area arrangement within a screen
  • Space: A logical workspace concept that can be associated with areas (especially LEAD areas) for shared state and history

Area Roles

const AREA_ROLE = {
  LEAD: 'LEAD',      // Primary workspace areas with shared state
  FOLLOW: 'FOLLOW',  // Secondary areas that follow LEAD areas
  SELF: 'SELF'       // Independent areas with local state only
} as const;

Tools Slot System

The tools slot system allows injecting components into predefined UI positions. The Tools component (alias for ToolsSlot) can be configured with different props:

<Tools areaType="apptitle">
  <Tools areaType="app">
    <Karmyc />
  </Tools>
</Tools>

Tools Component Props

interface ToolsProps {
  areaId?: string;           // Specific area ID for targeted tools
  areaType?: string;         // Area type for type-specific tools (default: 'app')
  areaState?: any;           // Current area state
  children: React.ReactNode; // Content to render
  style?: React.CSSProperties; // Inline style for container
  viewport?: Rect;           // Viewport dimensions
  nbOfLines?: number;        // Number of toolbar lines (default: 1)
}

API Reference

Core Hooks

useKarmyc(options, onError?)

Initializes the Karmyc system with configuration options.

interface IKarmycOptions {
  plugins?: IActionPlugin[];
  validators?: Array<{
    actionType: string;
    validator: (action: any) => { valid: boolean; message?: string };
  }>;
  initialAreas?: IArea[];
  keyboardShortcutsEnabled?: boolean;
  resizableAreas?: boolean;
  manageableAreas?: boolean;
  multiScreen?: boolean;
  allowStackMixedRoles?: boolean;
  previewDuringDrag?: boolean;
  builtInLayouts?: LayoutPreset[];
  initialLayout?: string;
  t?: (key: string, fallback: string) => string;
  spaces?: Record<string, ISpace>;
}

useArea()

Provides functions to manipulate areas and access their state.

const {
  createArea,
  removeArea,
  setActive,
  update,
  getActive,
  getById,
  getAll,
  getErrors
} = useArea();

useSpace()

Access state for spaces.

const { spaces, activeSpaceId, getSpaceById } = useSpace();

useRegisterAreaType(type, component, initialState, options)

Register a new area type.

useRegisterAreaType(
  'my-area',
  MyComponent,
  { data: 'default' },
  { displayName: 'My Area', role: AREA_ROLE.LEAD }
);

Additional Hooks

useAreaOptimized()

Optimized hook for area management with enhanced performance and extended functionality.

const { createArea, removeArea, splitArea, setRowSizes } = useAreaOptimized();
Specialized Area Hooks

Granular hooks for optimal performance:

const area = useAreaById(areaId);           // Get specific area
const activeArea = useActiveArea();         // Get active area
const allAreas = useAllAreas();             // Get all areas
const layout = useAreaLayoutById(areaId);   // Get area layout
const actions = useAreaActions();           // Get area actions
useAreaDragAndDrop(params?)

Provides drag and drop functionality for areas and placement overlay.

const { isDragging, handleDragStart, handleDragOver, handleDragEnd, handleDrop } =
  useAreaDragAndDrop({ id: 'area-1', type: 'my-area', state: {} });
useAreaKeyboardShortcuts(areaId)

Provides keyboard shortcuts for areas.

useAreaKeyboardShortcuts(areaId);
useContextMenu()

Provides context menu functionality.

const { openContextMenu, closeContextMenu } = useContextMenu();
useResizePreview()

Provides resize preview functionality.

const { showPreview, hidePreview, previewState } = useResizePreview();
useScreenManagement()

Provides screen management functionality.

const { createScreen, removeScreen, switchScreen } = useScreenManagement();
useAreaStack(areaId)

Provides area stacking functionality.

const { isChildOfStack, stackArea, unstackArea } = useAreaStack(areaId);
useActiveSpaceHistory()

Enhanced history bound to the active space.

const history = useActiveSpaceHistory();
useHistory(spaceId)

Provides enhanced history functionality with advanced features like action batching, diff tracking, and typed actions.

const {
  // State
  isActionInProgress,
  currentActionId,
  lastAction,
  stats,
  
  // Actions
  startAction,
  submitAction,
  cancelAction,
  undo,
  redo,
  
  // Utilities
  createSimpleAction,
  createSelectionAction,
  createTransformAction,
  
  // Checks
  canUndo,
  canRedo,
  
  // Getters
  getCurrentAction,
  getHistoryLength,
  getHistoryStats,
  
  // Management
  clearHistory,
  updateSelectionState
} = useHistory(spaceId);
useActiveSpaceHistory()

Provides enhanced history functionality for the currently active space.

const historyActions = useActiveSpaceHistory();
useTypedHistoryActions(spaceId)

Provides typed history actions for common operations.

const {
  create, update, delete, move, copy, paste,
  select, deselect, selectAll, deselectAll,
  group, ungroup, transform, rotate, scale, translate,
  timelineUpdate, keyframeAdd, keyframeRemove, keyframeUpdate,
  custom
} = useTypedHistoryActions(spaceId);
usePluginSystem()

Provides plugin system functionality.

const { registerPlugin, unregisterPlugin, getPlugins } = usePluginSystem();

Core Components

KarmycCoreProvider

Main provider that sets up the Karmyc environment.

<KarmycCoreProvider options={config}>
  {children}
</KarmycCoreProvider>

Karmyc

Primary component that renders layouts and areas.

<Karmyc />

Tools

System for injecting components into predefined UI slots.

<Tools areaType="app">
  <Karmyc />
</Tools>

Additional Components

AreaErrorBoundary

Error boundary component for areas.

<AreaErrorBoundary
  component={MyAreaComponent}
  areaId="area-1"
  areaState={{}}
  type="my-area"
  viewport={{ left: 0, top: 0, width: 300, height: 200 }}
/>
AreaPreview

Preview component used during drag operations.

<AreaPreview areaToOpen={{ position: { x: 100, y: 50 }, area: { type: 'my-area', state: {} } }} dimensions={{ x: 320, y: 200 }} />
AreaTabs

Tab component for stacked areas (internal usage via AreaStack).

ScreenSwitcher

Component for switching between screens.

<ScreenSwitcher />
KeyboardShortcutsViewer

Component for displaying keyboard shortcuts.

<KeyboardShortcutsViewer />
ContextMenu

Context menu component.

<ContextMenu />

Configuration

Built-in Layouts

You can define built-in layouts that users can switch between:

const builtInLayouts = [
  {
    id: 'default',
    name: 'Default Layout',
    config: { /* layout configuration */ },
    isBuiltIn: true
  }
];

Types and Interfaces

Core Types

// Area types
interface IArea<T = any> {
  id: string;
  type: AreaTypeValue;
  state?: Record<string, any>;
  spaceId?: string | null;
  viewport?: Rect;
  position?: Point;
  size?: { width: number; height: number };
  raised?: boolean;
  role?: AreaRole;
  isLocked?: boolean;
  enableFullscreen?: boolean;
  previousLayout?: { [key: string]: AreaLayout | AreaRowLayout };
  previousRootId?: string | null;
}

// Layout types
interface LayoutNode {
  id: string;
  type: 'area' | 'area_row';
  orientation?: 'horizontal' | 'vertical' | 'stack';
  areas?: Array<{ id: string; size: number }>;
}

// Additional types
interface Rect {
  top: number;
  left: number;
  width: number;
  height: number;
}

interface Point {
  x: number;
  y: number;
}

interface AreaLayout {
  // Layout configuration for areas
}

interface AreaRowLayout {
  // Layout configuration for area rows
}

// Space types
interface ISpace {
  id: string;
  name: string;
  sharedState: any;
  history: EnhancedHistoryAction[];
}

// Plugin types
interface IActionPlugin {
  id: string;
  name: string;
  onStoreChange?: (state: any, prevState: any) => void;
  onStoreInit?: (store: StoreApi<any>) => void;
  transformState?: (state: any) => Partial<any>;
  actions?: Record<string, (...args: any[]) => void>;
}

Enums and Constants

const AREA_ROLE = {
  LEAD: 'LEAD',
  FOLLOW: 'FOLLOW',
  SELF: 'SELF'
} as const;

const TOOLBAR_HEIGHT = 30;

Development

Available Scripts

  • yarn dev: Start development mode with watch
  • yarn build: Build the library
  • yarn bundle: Build the library (alias for build)
  • yarn test: Run tests
  • yarn test:watch: Run tests in watch mode
  • yarn test:coverage: Run tests with coverage
  • yarn demo:dev: Start the demo application in development mode
  • yarn demo:build: Build the demo application
  • yarn demo:ssr:dev: Start the SSR demo application in development mode
  • yarn demo:ssr:build: Build the SSR demo application
  • yarn demo:ssr:start: Start the SSR demo application

Project Structure

karmyc-core/
├── src/                    # Source code
│   ├── components/       # React components
│   │   ├── menus/       # Context menus
│   │   └── handlers/    # Event handlers
│   ├── core/             # Core logic and state management
│   │   ├── plugins/     # Plugin system
│   │   ├── registries/  # Component registries
│   │   ├── slices/      # Zustand store slices
│   │   └── types/       # Core type definitions
│   ├── hooks/            # Custom React hooks
│   ├── types/            # TypeScript type definitions
│   ├── utils/            # Utility functions
│   └── index.ts          # Main entry point
├── demo/                   # Demo application
│   ├── config/           # Demo configuration
│   └── shared/           # Shared demo components
└── docs/                   # Documentation

Acknowledgements

Karmyc core was extracted and derived from animation-editor by @alexharri - a web-based animation editor built with React, Redux, PIXI.js and HTML Canvas.

Karmyc Core is built upon several key libraries:

  • Zustand & Immer for state management
  • React DnD for drag-and-drop functionality
  • Lucide React for icons
  • @szhsin/react-menu for context menus

License