The secure-by-default, islands-first micro-framework.
π Website | π Documentation | π» Examples
- Install
- Hello World
- Why front.js?
- Core Concepts
- Examples
- API Reference
- Limitations
- Security Model
- Architecture
- Development
- Contributing
- License
npm install front-jsOr use directly via CDN:
<script type="importmap">
{
"imports": {
"front-js": "https://esm.sh/front-js@0.0.1",
"uhtml": "https://esm.sh/uhtml@4.5.11"
}
}
</script>1. HTML - Mark interactive areas with data-island:
Output your HTML with data-island, data-component, and data-props.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My App</title>
</head>
<body>
<div
data-island
data-component="Counter"
data-props='{"start": 10}'
></div>
<script type="importmap">
{
"imports": {
"uhtml": "https://esm.sh/uhtml@4.5.11"
}
}
</script>
<script type="module" src="./app.js"></script>
</body>
</html>2. JavaScript - Register your component and hydrate:
import { html, val, register, hydrate } from './src/index.js';
function Counter(props) {
const count = val(props.start || 0);
return () => html`
<div>
<button onclick=${() => count(count() - 1)}>-</button>
<span>Count: ${count()}</span>
<button onclick=${() => count(count() + 1)}>+</button>
</div>
`;
}
register('Counter', Counter);
hydrate();- π Islands Architecture: Hydrate only what needs interaction.
- π Secure by Default: Data flows via JSON only. No server closures.
- β‘ Tiny Runtime: <5KB gzipped. No build step required.
- π‘ Sanitized Rendering: Powered by
uhtmlto prevent XSS. - π― Fine-Grained Reactivity: Value-based state management (val/run/calc) with automatic dependency tracking.
Note: Built in response to recent security concerns with React Server Components (context).
Values are reactive primitives that track dependencies automatically:
import { val, run } from './src/index.js';
const count = val(0);
// Read value
count(); // 0
// Update value
count(5); // Updates to 5, notifies subscribers
// Read without subscribing
count.peek(); // 5 (doesn't track dependency)
// Auto-track in runs
run(() => {
console.log('Count changed:', count());
});Components are functions that return render functions:
function MyComponent(props) {
const state = val(props.initialValue);
return () => html`
<div>Value: ${state()}</div>
`;
}Components are hydrated from server-rendered HTML:
<div
data-island
data-component="MyComponent"
data-props='{"initialValue": 42}'
></div>Runs can clean up side effects like timers, event listeners, and subscriptions:
function Timer(props) {
const seconds = val(0);
run(() => {
const interval = setInterval(() => {
seconds(seconds() + 1);
}, 1000);
// Cleanup when run re-executes or component disposes
return () => clearInterval(interval);
});
return () => html`<div>Time: ${seconds()}s</div>`;
}Components can be manually disposed via container._front_dispose() for cleanup when using frameworks like HTMX:
// HTMX integration example
document.body.addEventListener('htmx:beforeSwap', (event) => {
const island = event.detail.target.querySelector('[data-island]');
if (island && island._front_dispose) {
island._front_dispose(); // Runs cleanup functions
}
});See the examples/ directory for complete working examples, including a Todo app that demonstrates all framework features.
To run examples:
npx serve .
# Navigate to http://localhost:3000/examples/index.htmlSee wiki/API.md for complete API documentation.
val(initialValue)- Create reactive valuerun(fn)- Run code reactivelycalc(fn)- Create calculated (derived) valueregister(name, componentFn)- Register componenthydrate(root?)- Hydrate islands in DOMhtml\template`` - Safe template literal (from uhtml)render(container, template)- Render template (from uhtml)
front.js is designed for server-rendered apps with Islands Architecture. See docs/LIMITATIONS.md for:
- Known constraints and trade-offs
- When NOT to use front.js
- Performance considerations
- Workarounds for common issues
front.js assumes the HTML is the Source of Truth.
- No eval: We never execute strings from the DOM.
- Explicit Props: Data must be serialized to JSON.
- Strict Content:
uhtmlescapes all values by default. - Component Validation: Component names are validated (alphanumeric only).
- Zero Trust: Invalid islands are logged and skipped, never crash the app.
front.js follows the "Islands Architecture" pattern:
- Server renders HTML with
data-islandmarkers - Client hydrates only interactive islands
- Data flows via JSON in
data-propsattributes - No magic - explicit component registration
See docs/BLUEPRINT.md for detailed architecture documentation.
# Install dependencies
npm install
# Build
npm run build
# Check bundle size
npm run size-check
# Run tests
npm test
# Format code
npm run formatSee CONTRIBUTING.md for development guidelines.
See DEVELOPMENT.md for how to run the website and KB locally, and deployment instructions.
ISC