Comparison with other Frameworks
Compare with Hooks
All components are local

In CS, a component (vs a hook) can be placed any where instead of being restricted at the top of render code and not in if, loop code like Hooks.

For example, here is a state declared in a IF condition:

cs(
    ["count1", ({}, next) => State({initValue: 0, next})],
    ({count1})=>(
        <div>
            Count 1: {count1.value}
            
            <button onClick={() => count1.change(v=>v+1)}>plus</button>
            
            {count1.value < 2 && cs(
                ["count2", ({}, next) => State({initValue: 0, next})],
                ({count2})=>(
                    <div>
                        Count 2: {count2.value}
                    </div>
                ),
            )}
        </div>
    ),
);
Here is the CodePen demo

In above example, there are 2 count states, but only count1 is declared at the top level stack. The second state "count2" will be created only if count1 value is > 10 and it will be used only inside that condition. Also when the that condition is no longer true, the state count2 would be destroyed.

Here is another example that a state is declared in a loop:

<div>
    A shopping list:
    
    {["Apple", "Orange", "Tomato"].map((item)=> cs(
        keyed(item),
        ["count", (_, next) => State({initValue: 0, next})],
        ({count}) => (
            <div key={item}>
                {item}: {count.value}
                <button onClick={() => count.change(v=>v+1)}>+</button>
                <button onClick={() => count.change(v=>v-1)}>-</button>
            </div>
        ),
    ))}
</div>
Here is the CodePen demo

In the above example, with each item in the shopping list, a different "count" state will be declared, and they can be interacted with (+ or -) independantly

Composition

In CS architecture, when a component need a state, it renders a state node into Virtual DOM tree, same goes for Static reference (or Memo in Hooks) or other effects like OnMounted, OnUnmounted... each function is rendered as a separated node into the Virtual DOM tree. Which means a component will be consisted of multiple "basic" nodes, each one is responsible for a function.

On the other hand, in Hooks, a component is always rendered as a Virtual DOM node, and each time that component needs a state, it will use a space in the state of that Virtual DOM node. This means no matter how many time you call "useState", there is only 1 node's state being accessed and used. Same goes for all other effects like useEffect, useMemo...

Powerful Custom Components

In CS, a custom Component is much more powerful than a Custom Hook

A custom component declared in CS way is capable of doing everything that a Custom Hook can do, and much more. A CS custom component can block the rendering, or loop rendering, and other actions to control the logic flow of the rendering (like combining 2 rendering flow).

Here is an example of a custom component which blocks the rendering altogether

const App = () => cs(
    ["blocker", (_, next) => Blocker({next})],
    ({blocker}) => (
        <div className="">
            Click this <button onClick={() => blocker.blockNow()}>button</button> and 
            everything will disappear
        </div>
    ),
);

const Blocker = ({next}) => cs(
    ["blocked", (_, next) => State({initValue: false, next})],
    ({blocked}) => !blocked.value && (
        next({blockNow: () => blocked.onChange(true)})
    ),
);
Here is the CodePen demo

In the above example, there is a custom component call Blocker. Blocker itself declares a state called "blocked" and with initial value of "false". If that "blocked" state somehow is "true", then the "next" function will not be called and "everything will disappear".

The Blocker component exports a method called "blockNow" which upon invoked will simply change the "blocked" state to "true" and "everything will disappear".

Here is another example that loops rendering:

const App = () => cs(
    ["shoppingItem", (_, next) => LoopMe({list: ["Apple", "Orange", "Tomato"], next})],
    ({shoppingItem}) => (
        <div>
            Item: {shoppingItem}
        </div>
    ),
);

const LoopMe = ({list, next}) => (
    list.map((item, i) => (
        <div key={i}>
            {next(item)}
        </div>
    ))
);
Here is the CodePen demo

In the above example, the LoopMe component receive a list of items, and all the rendering logic below it is repeated with each item in the list, which mean this code is actually rendered 3 times.

<div>
    Item: {shoppingItem}
</div>

Here is another example that combine 2 rendering flows:

const App = () => cs(
    ({}, next) => SecondFlow({next}),
    ({}) => (
        <div>
            This is flow 1
        </div>
    ),
);

const SecondFlow = ({next: rootNext}) => cs(
    ({}, next) => CombineFlow({flow1: rootNext, flow2: next}),
    () => (
        <div>
            This is flow 2
        </div>
    )
);

const CombineFlow = ({flow1, flow2}) => <>
    {flow1()}
    {flow2()}
</>;
Here is the CodePen demo

In the above example an additional content is added to the main rendering code. This technique is important to implement components like Tooltip or Modal, where "SecondFlow" component declares how that Tooltip (or Modal) looks like, and the CombineFlow make sure that the additional content only appears when user hover their mouse over a text (Tooltip) or click a button to open the Modal.