Introduction
PulsePoint is a backend-agnostic reactive engine. It lets you use a React-style mental model (state, effects, components, composition) directly in HTML with a tiny browser runtime, while keeping your server in full control of routing, data, and templates.
Why PulsePoint?
Modern web development often forces a choice: build a complex Single Page Application (SPA) with a heavy build step, or stick to server-rendered pages enhanced with ad-hoc imperative DOM scripts for interactivity.
PulsePoint bridges this gap: render your initial HTML on the server (PHP, Node, Python, Rust, C#, or Go) and "sprinkle" fine-grained reactivity with a tiny browser runtime. Complex patterns like infinite scroll or paginated lists become trivial — make a fetch call for JSON, store the response in a reactive state, and PulsePoint will efficiently append or replace only the changed nodes. This makes loading and updating lists dynamic, predictable, and easy to implement.
PulsePoint Architecture
Synchronized State Architecture
PulsePoint unlocks a powerful "Hybrid" workflow. Your backend can initialize a component by passing a simple JSON array into the state variable during the initial server render.
When a CRUD operation occurs, the browser requests data, not UI. The server returns only the updated JSON section. PulsePoint receives this fresh data and automatically updates the DOM where necessary.
Server Response
Returns raw JSON. significantly smaller payload than HTML fragments.
{"items": [...updated_list]}
PulsePoint Reaction
Detects state change and surgically updates the DOM. Frontend and Backend models stay perfectly in sync.
Visualizing the separation: The Server handles Logic & Data structure, while PulsePoint handles the View & Reactivity.
Technical Comparison
How PulsePoint compares to other popular architectural patterns regarding data transmission and rendering.
| Approach | Initial Load | Updates (CRUD) | Mental Model |
|---|---|---|---|
| Traditional SPA (React/Vue) | Slow (Large JS Bundle) | Fast (JSON Data) | Frontend manages everything |
| HTML Over The Wire (HTMX) | Fast (Server Rendered) | Moderate (HTML Fragments) | Backend returns UI chunks |
| PulsePoint | Fast (Server Rendered) | Fastest (JSON State Only) | Backend Logic + Reactive View |
* PulsePoint allows you to keep the efficiency of JSON data transfer without sacrificing the SEO and speed of Server Side Rendering.
Zero Build Step
No Webpack, Vite, or complex compilers required. Just include the script tag and start writing reactive HTML.
Backend Agnostic
PulsePoint doesn't care what generates your HTML. It works perfectly with Express, Django, Laravel, Symfony, raw PHP, C#, Go, Python, or Rust.
Surgical Updates
Unlike Virtual DOM libraries, PulsePoint updates only the exact text node or attribute that changed, ensuring maximum performance.
Type-Safe Runtime
Built with TypeScript, providing a robust developer experience with helpful console warnings during development.
React Mental Model, PulsePoint Syntax
PulsePoint follows the core ideas of React: state, effects, components, composition, children, lists, portals, and so on. If you already know React, you already know how to think in PulsePoint — the main difference is that the syntax stays close to HTML instead of JSX.
React concepts vs PulsePoint equivalents
| Concept | React | PulsePoint |
|---|---|---|
| State declaration |
const [count, setCount] = useState(0)
|
const [count, setCount] = pp.state(0)
|
| Effect / side effects |
useEffect(() => { ... }, [deps])
|
pp.effect(() => { ... }, [deps])
|
| Refs / DOM access |
const inputRef = useRef(null)
|
const inputRef = pp.ref(null)
|
| List rendering |
items.map(item => <li key={item.id}>...</li>)
|
<template pp-for="item in items">...</template>
|
| Conditional rendering |
{condition && <span>Visible</span>}
|
{condition ? 'Visible' : ''} or using hidden attributes
|
| Text interpolation |
<h1>Count is: {count}</h1>
|
<h1>Count is: {count}</h1>
|
| Props |
<Button disabled={isLoading} />
|
<Button disabled="{isLoading}" />
|
| Component declaration |
function Button(props) { ... }
|
<div pp-component="Button">...</div>
|
| Component children |
<Layout><Header />...</Layout>
|
Parent HTML passed as children into a pp-component
|
| Context |
const ThemeContext = createContext(...)
|
Context APIs exposed by PulsePoint, consumed inside components
|
| Portals |
createPortal(children, container)
|
const portalId = pp.createPortal(portalContent, target);
|
| Spread props |
<Button {...props} />
|
<button pp-spread="{...buttonProps}">...</button>
|
| Two-way binding |
value={value} onChange={e => setValue(e.target.value)}
|
value="{value}" oninput="setValue(event.target.value)"
|
The core idea is simple: think in React, write HTML. PulsePoint keeps the surface area small — a tiny set of primitives (state, effect, ref, loop, spread, components) that cover the same reactivity cases you already know.
At a Glance
Here is a simple counter component. Notice how the state is declared in standard JavaScript, but bound directly to the HTML attributes.
<h1>Count is: {count}</h1>
<button
onclick="setCount(count + 1)"
disabled="{count >= 10}">
Increment
</button>
<button
onclick="setCount(count - 1)"
disabled="{count <= 0}">
Decrement
</button>
<script type="text/pp">
const [count, setCount] = pp.state(0);
</script>
Seamless Integration & Real-Time Power
Because PulsePoint sits directly in the browser, it plays perfectly with the entire JavaScript ecosystem. There are no wrappers or adapters needed—just call your functions.
Effortless Integration
Need to use a charting library, a date picker, or a toaster notification? Since PulsePoint variables are just JavaScript, you can pass state directly to third-party functions inside your script tags or Mustache templates.
-
✓
Call external functions directly from
onclickevents. - ✓ Pass reactive state into third-party configs easily.
Native Real-Time & Logic
PulsePoint turns standard WebSockets into reactive powerhouses. Handle all your data validation logic directly in the script tag, then simply update the state.
The HTML UI automatically reflects the valid data—no complex DOM query selectors required.
<ul>
<template pp-for="msg in messages">
<li class="message">{msg.text}</li>
</template>
</ul>
<script type="text/pp">
const [messages, setMessages] = pp.state([]);
// 1. Native JS WebSocket
const socket = new WebSocket('ws://api.example.com/chat');
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
// 2. Logic & Validation in plain JS
if (!data.isValid || data.isSpam) return;
// 3. Update State -> PulsePoint updates HTML automatically
// No manual DOM manipulation needed!
setMessages(prev => [...prev, data]);
// 4. Easy Third-Party Integration
Toastify({ text: "New Message received!" }).showToast();
};
</script>