Skip to content
@Zignal-React

Zignal

Lightweight, reactive tools for scalable state management and synchronization in modern React apps.
Zignal Logo

Zignal

A lightweight, reactive state management library for React that makes state synchronization effortless.

✨ Features

  • 🪶 Lightweight: Minimal bundle size with zero dependencies
  • ⚡ Reactive: Automatic component updates when state changes
  • 🔄 Sync Anywhere: URL parameters, localStorage, sessionStorage, or across browser tabs
  • 🎯 Type-Safe: Full TypeScript support with excellent type inference
  • 🧩 Composable: Mix and match different sync strategies
  • 🚀 Simple API: Intuitive hooks-based interface

🎮 Try It Live

→ Interactive Examples on StackBlitz

🚀 Quick Start

npm install @zignal/core
import { createZignal } from '@zignal/core';

// Create a reactive counter
const useCounter = createZignal(0);

function Counter() {
  const [count, setCount] = useCounter();
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

📦 Packages

Core

Extensions

🎯 Examples

Simple Counter

import { createZignal } from '@zignal/core';

const useCounter = createZignal(0);

function SimpleCounter() {
  const [count, setCount] = useCounter();
  return (
    <div>
      <h3>Count: {count}</h3>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Persistent Counter (localStorage)

import { createZignal } from '@zignal/core';
import { write } from '@zignal/persist';

const useCounter = write(createZignal(0), { key: 'my-counter' });

function PersistentCounter() {
  const [count, setCount] = useCounter();
  // State automatically persists to localStorage
  return <div>Count: {count}</div>;
}

URL Synced Counter

import { createZignal } from '@zignal/core';
import { buildQueryString } from '@zignal/paramagic';

const useUrlCounter = buildQueryString(
  createZignal({ count: 0 }), 
  { key: 'count' }
);

function UrlCounter() {
  const [state, setState] = useUrlCounter();
  // State syncs with URL parameters automatically
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => setState({ count: state.count + 1 })}>
        Increment
      </button>
    </div>
  );
}

Cross-Tab Sync

import { createZignal } from '@zignal/core';
import { broadcast } from '@zignal/sync';

const useSharedCounter = broadcast(createZignal(0), { key: 'shared-counter' });

function SharedCounter() {
  const [count, setCount] = useSharedCounter();
  // Changes sync across all open tabs automatically
  return <div>Shared Count: {count}</div>;
}

🏗️ Architecture

Zignal follows a simple but powerful pattern:

  1. Create a zignal with createZignal(initialValue)
  2. Enhance it with sync strategies (persist, URL, broadcast)
  3. Use it in components like any React hook
// 1. Create
const useCounter = createZignal(0);

// 2. Enhance (optional)
const usePersistentCounter = write(useCounter, { key: 'counter' });
const useUrlCounter = buildQueryString(useCounter, { key: 'count' });
const useSharedCounter = broadcast(useCounter, { key: 'shared' });

// 3. Use
function MyComponent() {
  const [count, setCount] = useCounter(); // or any enhanced version
  return <div>{count}</div>;
}

🔧 Advanced Usage

Multiple Sync Strategies

import { createZignal } from '@zignal/core';
import { write } from '@zignal/persist';
import { buildQueryString } from '@zignal/paramagic';

// Combine URL sync + localStorage persistence
const useAdvancedCounter = write(
  buildQueryString(createZignal({ count: 0 }), { key: 'count' }),
  { key: 'advanced-counter' }
);

Custom Serialization

import { buildQueryString } from '@zignal/paramagic';

const useCustomSync = buildQueryString(createZignal(new Date()), {
  key: 'date',
  serialize: (date) => date.toISOString(),
  deserialize: (str) => new Date(str)
});

🤝 Contributing

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

📄 License

MIT © Zignal Team


Try the examples →

Pinned Loading

  1. zignal-core zignal-core Public

    TypeScript 1

  2. zignal-persist zignal-persist Public

    TypeScript 1

  3. zignal-sync zignal-sync Public

    TypeScript 1

Repositories

Showing 6 of 6 repositories

Top languages

Loading…

Most used topics

Loading…