For Developers. By Developers.
Root.js is a full-featured web development tool that comes with a built-in CMS.
Explore features
TSX to HTML. 0kB JS to browser.
TSX server components render HTML. That's it. The framework does not require any client-side JavaScript to run. Add web components for interactivity.
// @/routes/index.tsx
export default function Page() {
return <h1>Hello, world!</h1>;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
Powered under the hood by:
Which means the framework has all the modern features you have come to love and expect (SCSS modules, HMR, etc.).
Islands based on Web Components.
// @/routes/index.tsx
export default function Page() {
return (
<root-counter>
<button>Count</button>
<div class="value">0</div>
</root-counter>
);
}
// @/elements/root-counter.ts
class RootCounter extends HTMLElement {
value = 0;
connectedCallback() {
const button = this.querySelector('button');
const valueEl = this.querySelector('.value');
if (button && valueEl) {
button.addEventListener('click', () => {
this.value += 1;
valueEl.textContent = String(this.value);
});
}
}
}
if (!customElements.get('root-counter')) {
customElements.define('root-counter', RootCounter);
}
Dependencies are auto‑injected.
When a page is rendered, custom element usage is auto‑detected and the file dependencies are auto‑injected into the page.
Plays nicely with VS Code.
Tag your custom element props in TypeScript and get code autocompletions. No extra plugins needed; works with Visual Studio Code right out of the box.
Visualize your sitemap.
Routing is based on the filesystem (inspired by Next.js). SSG and SSR supported. Add Express.js server middleware via plugins.
Localization as a first-class feature.
Routes are locale-aware. Built-in translations system via hooks.
// @/routes/index.tsx
import {useTranslations} from '@blinkk/root';
export default function Page() {
const t = useTranslations();
return <h1>{t('Hello, world!')}</h1>
}
// @/translations/fr.json
{
"Hello, world!": "Bonjour le monde!"
}