Skip to content

Instantly share code, notes, and snippets.

@Munawwar
Last active October 8, 2025 17:20
Show Gist options
  • Save Munawwar/4b6085ec29ed5c741bfcd6c21522a93f to your computer and use it in GitHub Desktop.
Save Munawwar/4b6085ec29ed5c741bfcd6c21522a93f to your computer and use it in GitHub Desktop.
Component model that makes React chill!

Chill Pill - Relax React!

A component model that makes React react less!

Overview

Chill Pill provides a simpler way to write React components without the complexity of hooks like useCallback, useMemo, and dealing with stale closures.

Example

import CalmDownReact from "./chill-pill.js";

const Counter = CalmDownReact(function MyComponent({ $, render }) {
  let state = 0;
  // Shorthand for: `() => { state++; render(); }`
  const updateState = $(() => state++);

  // Callbacks are created once! Like how it should have always been!
  const onClick = () => updateState();

  // No more stale-closure problems! You can just access the latest state!

  // You know, you don't need useRef anymore? Just use createRef!

  // Yes! Return a render function!
  // Stop creating callbacks inside the render function like a savage.
  return function renderFunc(props) {
    return (
      <div>
        Counter: <button onClick={onClick}>{state}</button>
      </div>
    );
  }
});
import { useState, useMemo, useEffect, useCallback, createElement } from "react";
export default function ChillPill(InitComponent) {
let renderInProgress = false;
let onMountCallbacks = [];
const onMount = (callback) => {
onMountCallbacks.push(callback);
}
return function ChillPillComponent(props) {
renderInProgress = true;
const [, forceRefresh] = useState(0);
const render = useCallback(() => {
if (renderInProgress) return;
forceRefresh((x) => x + 1);
}, []);
const $ = useCallback((callback) => () => {
callback();
render();
}, []);
const Component = useMemo(() => {
try {
return InitComponent({ $, render, onMount });
} finally {
renderInProgress = false;
}
}, []);
useEffect(() => {
const unmountedCallbacks = onMountCallbacks.map((callback) => callback());
return () => {
unmountedCallbacks.forEach((callback) => callback?.());
};
}, []);
let vNode = null;
try {
vNode = createElement(Component, props);
} finally {
renderInProgress = false;
}
return vNode;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New component model examples</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css">
<style>
:root {
--text-color: #222;
--bg-color: #fff;
--border-color: #ccc;
--input-bg-color: #fff;
--disabled-bg-color: #f0f0f0;
--hover-bg-color: rgba(0, 0, 0, 0.1);
}
html[data-theme="dark"] {
--text-color: #e0e0e0;
--bg-color: #222;
--border-color: #666;
--input-bg-color: #444;
--disabled-bg-color: #333;
--hover-bg-color: rgba(255, 255, 255, 0.1);
}
body {
font-family: 'Roboto', sans-serif;
padding: 20px;
transition: background-color 0.3s, color 0.3s;
min-width: 320px;
max-width: 700px;
margin: 0 auto;
background-color: var(--bg-color);
color: var(--text-color);
}
#root {
width: 100%;
}
label {
display: block;
margin: 5px 0;
font-weight: 700;
font-size: larger;
}
/* Style for example elements */
button,
p {
color: var(--text-color);
}
button {
background-color: var(--input-bg-color);
border-color: var(--border-color);
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: var(--hover-bg-color);
}
.demoContainer {
padding: 20px;
background-color: #f0f0f0;
border-radius: 15px;
margin-bottom: 20px;
margin-top: 20px;
}
.badge {
appearance: none;
border: none;
outline: none;
display: inline-block;
background-color: #222;
color: #fff;
padding: 8px 16px;
border-radius: 20px;
margin: 4px;
cursor: pointer;
user-select: none;
}
.badge:hover {
background-color: #222;
color: #fff;
}
</style>
<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/preact@10?dev",
"preact/hooks": "https://esm.sh/preact@10/hooks?dev",
"preact/jsx-runtime": "https://esm.sh/preact@10/jsx-runtime?dev",
"preact/compat": "https://esm.sh/preact@10/compat?dev",
"htm": "https://esm.sh/htm?dev",
"react": "https://esm.sh/react@18?dev",
"react-dom": "https://esm.sh/react-dom@18?dev",
"react-dom/client": "https://esm.sh/react-dom@18/client?dev"
}
}
</script>
</head>
<body>
<h2>Relax React!</h2>
<div style="margin-top: 30px;">
<h3>A component model that make React react less!</h3>
<pre><code class="language-jsx">import CalmDownReact from "./chill-pill.js";
const Counter = CalmDownReact(function MyComponent({ $, render }) {
let state = 0;
// Shorthand for: `() => { state++; render(); }`
const updateState = $(() => state++);
// Callbacks are created once! Like how it should have always been!
const onClick = () => updateState();
// No more stale-closure problems! You can just access the latest state!
// You know, you don't need useRef anymore? Just use createRef!
// Yes! Return a render function!
// Stop creating callbacks inside the render function like a savage.
return function renderFunc(props) {
return (
&lt;div&gt;
Counter: &lt;button onClick={onClick}&gt;{state}&lt;/button&gt;
&lt;/div&gt
);
}
});
</code></pre>
</div>
<h3>Heresy you say?</h3>
<div id="root"></div>
<script type="module">
import './example.js';
</script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/javascript.min.js"></script>
<script>
hljs.highlightAll();
</script>
</body>
</html>
import htm from "htm";
import { createElement } from "react";
import { createRoot } from "react-dom/client";
const html = htm.bind(createElement);
import ChillPill from "./chill-pill.js";
const Counter = ChillPill(({ $ }) => {
let state = 0;
const updateState = $(() => state++);
// Callbacks are created once! Like how it should have always been!
const onClick = () => updateState();
return function render(props) {
return html`<div>
Counter: <button onClick=${onClick}>${state}</button>
</div>`
}
});
function App() {
return html`<${Counter} />`;
}
const root = createRoot(document.getElementById("root"));
root.render(html`<${App} />`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment