ReblendJS is a modern frontend library that combines the best of React and Web Components. It provides a simple, high-performance API for building reusable UI components, with native support for async rendering, hooks, and seamless integration with both React and standard HTML.
Hereβs an overview of the main project structure. Each package is explained below:
reblendjs/
βββ packages/
β βββ reblend-bootstrap/ # Bootstrap component wrappers for ReblendJS
β βββ reblend-deep-equal-iterative/ # Deep equality checking utilities
β βββ reblend-hooks/ # Built-in hooks (state, effect, etc.)
β βββ reblend-router/ # Client-side routing for ReblendJS apps
β βββ reblend-routing/ # Routing utilities and helpers
β βββ reblend-template-test/ # Template and test utilities
β βββ reblend-typing/ # TypeScript type definitions
β βββ reblend-ui/ # Core UI components and primitives
βββ tasks/ # Project scripts and automation
βββ README.md # Project documentation (this file)
βββ package.json # Project metadata and dependencies
βββ ... # Other configuration and support files
What Each Package Does:
- reblend-bootstrap/: Provides Bootstrap-styled components for use with ReblendJS.
- reblend-deep-equal-iterative/: Utilities for deep equality checks, useful for state comparison and memoization.
- reblend-hooks/: Collection of built-in hooks (like
useState,useEffect) for state and lifecycle management. - reblend-router/: Implements client-side routing for single-page applications.
- reblend-routing/: Additional routing helpers and utilities, inspired by Express.js.
- reblend-template-test/: Templates and utilities for testing ReblendJS components and bootstrapping new projects.
- reblend-typing/: TypeScript type definitions for strong typing and IDE support.
- reblend-ui/: Core UI primitives and reusable, headless components.
- Standard HTML & React Attributes β Write components using familiar syntax.
- JSX Support β Use
for,style(as a string),class(asclassNames), and standard attributes. - React Component Compatibility β Use React components within ReblendJS.
- Uses React's Build Tools β No need to change your existing setup.
- Functional Components Compile to Classes β Optimized for performance.
- Single Execution for Functional Components β No unnecessary re-renders.
- Web Component Native Support β Directly renders existing
HTMLElementinstances without wrappers. - Simple API & Easy to Learn β Minimal boilerplate, quick to get started.
- Built-in Hooks Support β Manage state and side effects seamlessly.
- Component-Level State Management β Each element holds its own state.
- No Mixed or Async State Rendering β Eliminates issues with pre/post rendering.
- Faster Rendering β State is localized within each element, reducing unnecessary updates.
- Async Components & Rendering β Out-of-the-box support for async components and lazy loading.
ReblendJS supports async components and async rendering natively. You can return a Promise from your component, enabling features like code-splitting and conditional lazy loading without extra libraries.
Example:
import Reblend from "reblendjs";
import { useIsAdmin } from "../../lib/hooks";
export async function AdvertPage() {
const isAdmin = useIsAdmin();
return (
<>
{isAdmin
? import("../admin/advert/admin-advert").then((m) => m.default)
: import("./advert").then((m) => m.default)}
</>
);
}Just use async components and return Promises or dynamic importsβReblendJS will handle the rendering automatically.
To quickly set up a new ReblendJS project with TypeScript, use:
npx create-reblend-app --template typescript ./my-appAlternatively, install ReblendJS manually:
npm install reblendjsor
yarn add reblendjsReblendJS uses mountOn to attach components to the DOM:
import Reblend from 'reblendjs';
import App from './App';
Reblend.mountOn('root', App);ReblendJS recommends using functional components for better performance, as they are efficiently compiled into class components:
import Reblend, { useState } from 'reblendjs';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
Reblend.mountOn('root', Counter);ReblendJS fully supports JSX attributes, including:
for(instead ofhtmlForin React)style(as a string, unlike React's object-based approach)class(asclassNames)- Standard attributes (
id,name,placeholder, etc.)
Example:
const FormExample = () => {
return (
<form>
<label for="name">Name:</label>
<input id="name" type="text" placeholder="Enter your name" />
<button
class="btn btn-primary"
style="background-color: blue; padding: 10px;"
>
Submit
</button>
</form>
);
};
Reblend.mountOn('root', FormExample);ReblendJS is ideal for:
- Building Web Components β Create reusable elements without React wrappers.
- Optimizing Performance β When Reactβs Virtual DOM is too heavy.
- Progressive Enhancement β Use ReblendJS alongside native HTML.
- Embedding in Non-React Projects β Works well in vanilla JS applications.
| Feature | ReblendJS | ReactJS |
|---|---|---|
| Standard HTML Attributes | β Supports all | β Supports all |
JSX for, style, class |
β Fully supported | β htmlFor, style as an object, className |
| React Component Support | β Fully Compatible | β Native |
| Functional Components | β Compiled to Classes | β Functional with Hooks |
| Hooks | β Supported | β Supported |
| Web Component Support | β Native (renders without wrapper) | β Requires wrappers like Reblend.createElement |
| State Management | β Localized in elements | β Centralized (React Context, Redux) |
| Rendering Performance | β Faster (isolated state per element) | |
| Build Tool | β Uses React's toolchain | β Uses its own build tools |
| Learning Curve | β Simpler syntax, minimal setup |
Hereβs an example of creating a button that toggles a modal:
import { Button } from 'react-bootstrap';
import Reblend, { useState } from 'reblendjs';
import Modal from 'react-bootstrap/Modal';
export function MyVerticallyCenteredModal(props) {
return (
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
closeButton
>
<Modal.Header>
<Modal.Title id="contained-modal-title-vcenter">
Modal heading
</Modal.Title>
</Modal.Header>
<Modal.Body>
<h4>Centered Modal</h4>
<p>
Cras mattis consectetur purus sit amet fermentum. Cras justo odio,
dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac
consectetur ac, vestibulum at eros.
</p>
</Modal.Body>
<Modal.Footer>
<Button onClick={props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
const App = () => {
const [modalShow, setModalShow] = useState(false);
const toggleModal = () => {
setModalShow(!modalShow);
};
return (
<div>
<Button variant="primary" onClick={toggleModal}>
Toggle Modal
</Button>
<MyVerticallyCenteredModal show={modalShow} onHide={toggleModal} />
</div>
);
};
Reblend.mountOn('root', App);We welcome contributions! Feel free to submit issues or pull requests.
- Fork the repository.
- Create a new branch.
- Commit your changes.
- Open a pull request.