New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

statekit-lite

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

statekit-lite

Minimal proxy-based global state manager for React with nested access, persist, watch, devtools, and realtime sync via plugins.

latest
Source
npmnpm
Version
1.3.1
Version published
Maintainers
1
Created
Source

🧠 statekit-lite

A minimal global state manager for React

  • 🔥 has no dependencies (except immer)
  • ⚛️ Fully typed reactive access
  • 🔁 .get(), .set(), .use() and .watch() on any nested path
  • 📦 Redux DevTools compatible
  • 🌐 Realtime support with SSE plugin

✨ Key Features

  • 🔥 Proxy-based access with automatic nested structure creation

  • 🔥 Typed access and reactivity with .get() / .set() / .use()

  • 📝 Watch outside React with .watch(fn)

  • 💾 Persist to localStorage

  • ⚛️ Redux DevTools integration

  • ✨ SSR-safe by design

  • 🌐 Realtime updates via ssePlugin()

  • 🧩 Plugin system — extend behavior with middleware-style plugins

  • 🌐 Realtime sync via:

    • ssePlugin() – Server-Sent Events
    • syncPlugin() – universal sync layer (WebSocket, polling, etc.)
    • supabasePlugin() – Supabase integration (with optional fallback polling)

📦 Installation

# Using npm
npm install statekit-lite

# Using yarn
yarn add statekit-lite

# Using pnpm
pnpm add statekit-lite

📌 Examples

crate state

import React from "react";
import { createStore } from "statekit-lite";

// Create store with persist + devtools
const userStore = createStore({
  user: {
    name: 'Anon',
    age: 25
  }
}, {
  persist: {
    key: 'user'     //  (path key from local storage) persist save, and auto load 
  },
  immer: true 
});

full example of possible use

import React from "react";
import { createStore } from "statekit-lite";

// Create store with persist + devtools
const userStore = createStore({
  user: {
    name: 'Anon',
    age: 25
  }
}, {
  persist: {
    key: 'user'
  },
  devtools: {
    name: "userStore"
  },
  immer: true
});

// Component that shows state
function Display() {
  const user = userStore.user.use();

  return (
    <div style={{ marginLeft: '45%', marginTop: '15%', fontSize: '24px', color: 'silver' }}>
      {user.age}
    </div>
  );
}

// Component that updates state every second
function Updater() {
  React.useEffect(() => {
    const i = setInterval(() => {
      userStore.user.arr[1].set({ t: 1 }); // creates nested array structure
      userStore.user.test.test.set({ a: 1 }); // creates nested object structure
      userStore.user.age.set(age => age + 1); // updates with function

      console.log(userStore.user.get());
    }, 1000);

    return () => clearInterval(i);
  }, []);

  return null;
}

// Root App
export function App() {
  return (
    <div>
      <Updater />
      <Display />
    </div>
  );
}

✅ Explanation

  • createStore(...) creates a globally accessible reactive store
  • userStore.user.age.use() subscribes to changes and re-renders Display
  • set(...) auto-creates nested paths like arr[1] or test.test
  • persist keeps state across reloads using localStorage
  • devtools logs each .set() call into Redux DevTools

watch(fn) — programmatic change listener

userStore.user.watch((user) => {
  console.log("state changed: ", user);
});

🧩 Plugins

statekit-lite supports realtime sync via plugins.

🔄 syncPlugin(options)

A universal plugin that connects any part of the store to remote data (SSE, WebSocket, polling, etc.).

✅ Features

  • Reactive sync from remote
  • Optional pushUpdate to server
  • Works on any nested path
  • Supports both full-replace and updater modes
  import { syncPlugin, createStore } from 'statekit-lite';

  const store = createStore({ user: { name: '', age: 0 } }, {
    plugins: [
      syncPlugin({
        subscribe: (emit) => {
          const source = new EventSource('http://localhost:3000/events');
          source.onmessage = (e) => emit(JSON.parse(e.data));
          return () => source.close();
        },
        pushUpdate: (data) => {
          fetch('/update', {
            method: 'POST',
            body: JSON.stringify(data),
            headers: { 'Content-Type': 'application/json' },
          });
        },
        debug: true,
      }),
    ]
  });

or ssePlugin

Convenience wrapper around syncPlugin for Server-Sent Events (SSE). Enable realtime updates from a server:

  import { createStore, ssePlugin } from 'statekit-lite';

  const store = createStore({
    messages: [] as string[],
  }, {
    plugins: [
      ssePlugin<string>({
        url: 'http://localhost:3000/events',
        path: ['messages'],
        mode: 'push',
        mapper: (data) => data.message
      })
    ]
  });

  // example component real time update SSE
  function Messages() {
    const list = store.messages.use();
    return <ul>{list.map((msg, i) => <li key={i}>{msg}</li>)}</ul>;
  }
  type SSEPluginOptions<T> = {
    url: string;                      // 🔌 URL SSE endpoint
    path?: (string | number)[];       // 🔑 (optional) Path inside store to update
    mapper?: (data: any) => T;        // 🧠 (optional) transform before storing
    mode?: 'set' | 'push';            // 🔁 (optional) 'set' (default) or 'push' to array (push mode is ideal for appending to arrays, set to override the target value)
  }

🔌 Realtime Server Example (Node.js + Express)

Below is a minimal SSE backend you can use to push real-time updates into statekit-lite.

💡 → Example of use

  // server.ts
  import express from 'express';
  import cors from 'cors';

  const app = express();
  app.use(cors());
  app.use(express.json());

  let clients: Response[] = [];

  // SSE endpoint: clients connect here
  app.get('/events', (req, res) => {
    res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    clients.push(res);
    console.log('👤 Client connected');

    req.on('close', () => {
      clients = clients.filter(c => c !== res);
      res.end();
      console.log('❌ Client disconnected');
    });
  });

  // Send an event to all clients
    app.post('/send', (req, res) => {
      const msg = req.body?.message ?? 'Пустое сообщение';
      const payload = JSON.stringify({ data: msg });
      
      for (const client of clients) {
          client.write(`data: ${payload}\n\n`);
      }

      res.sendStatus(200);
  });

  app.listen(3000, () => {
    console.log('🚀 SSE server running at http://localhost:3000/events');
  });

🗄️ supabase Plugin

A plugin that synchronizes your entire store with a Supabase table in key-value format.

Ideal for:

  • Realtime collaboration
  • Shared persistent state across clients
  • Saving editor/project/user states per session or user ID

To use supabasePlugin, install Supabase client:

  npm install @supabase/supabase-js

✅ Features

  • Bidirectional sync with Supabase (jsonb)
  • Works with any key and field (custom primary key supported)
  • Realtime updates using postgres_changes
  • Auto-insert on first load
  • Full store hydration and push on change

🧩 Table structure

create table kv_store (
  key text primary key,
  value jsonb,
  updated_at timestamp default now()
);

⚠️ Enable Realtime in Supabase

To receive realtime updates from Supabase, you must explicitly enable Realtime for your table.

  • Go to your project in Supabase Dashboard
  • Navigate to Table Editor → kv_store
  • Click on the Realtime tab
  • Toggle the switch to Enable Realtime

Otherwise, .on('postgres_changes', ...) will not trigger any events.

🔧 Usage

  import { createStore, supabasePlugin } from 'statekit-lite';

  const store = createStore({ count: 0 }, {
    plugins: [
      supabaseKVPlugin({
        url: 'https://your-project.supabase.co',
        anon_key: 'your-anon-key',
        table: 'kv_store',
        key: 'session-123',        // identifier of this row
        field: 'value',            // optional (default = 'value')
        primary_key: 'key',        // optional (default = 'key')
        debug: true,
        polling: 3000,             // ← (optional) fallback polling every 3s if Realtime is not working
      })
    ]
  });

This plugin automatically:

  • Loads the initial state from Supabase
  • Subscribes to realtime changes for the same key
  • Pushes new state on every .set() or .update()

✅ Supports multi-user setups (just change the key value per user/project)

🧩 When to Use

  • Global state in React SPA
  • Forms, visual editors, configuration panels
  • Embedded apps and UI libraries
  • Minimal, fast alternative to Redux/Zustand
  • Real-time dashboards, chats, logs (via SSE plugin)
  • Server-driven UIs or status syncing

Keywords

react

FAQs

Package last updated on 06 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