Skip to main content

Introduction

Welcome to Refract

Version: Production

This is the latest documentation for Refract.
For experimental features, see the Staging docs.

Refract robot

Refract is a reactive, composable, and optics-powered JavaScript framework for building user interfaces with precision. Whether you’re a seasoned React developer or exploring declarative UI design, Refract offers a refreshing take on frontend development.

"A new way to build reactive UIs — clear, declarative, and optics-powered."

Why Refract?

Refract is designed for developers who are tired of juggling complex state logic, boilerplate, and frameworks that get in the way of building. Imagine being able to focus on what your app should do rather than how to wire everything together.

With Refract, you spend less time fighting your tools and more time creating clear, predictable, and scalable UIs. It’s not about reinventing the wheel—it’s about giving you a sharper, more flexible lens to build with.

Here’s what makes it stand out:

  • Refractions: Reactive state units
  • Lenses: Scoped state access and lifecycle handling
  • Optics: Reusable reactive logic patterns
  • Optical Composition: Modular, dependency-aware UI logic reuse
  • Compiler Optimizations: For better performance and tree-shaking
info

Refract is designed with a focus on modularity, reactivity, and developer experience. It encourages clean abstractions that make complex UI logic easier to build, maintain, and scale.

Core Concepts

Components

In Refract, components are created using createComponent(). Think of them like React components, but without the boilerplate:

import { createComponent } from 'refract';

const Counter = createComponent(({ lens }) => {
const count = lens.useRefraction(0);

return (
<button onClick={() => count.set(count.value + 1)}>
Clicked {count.value} times
</button>
);
});

Refractions

Refractions are the reactive state units in Refract:

import { useRefraction } from 'refract';

const theme = useRefraction('light');

theme.set('dark');
console.log(theme.value); // 'dark'

They update your UI automatically when changed.

Lenses

Lenses connect component logic to reactive state and side-effects:

const TodoList = createComponent(({ lens }) => {
const todos = lens.useRefraction([]);
lens.useEffect(() => {
fetchTodos().then(todos.set);
}, []);
});

Optical Composition

Encapsulate logic using useOptic():

function useMousePosition() {
const pos = useRefraction({ x: 0, y: 0 });

useOptic(() => {
const handler = e => pos.set({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', handler);
return () => window.removeEventListener('mousemove', handler);
}, []);

return pos;
}

Side Effects

Use useEffect, useOptic, and useFlash to handle side effects:

  • useEffect: Standard reactive effect

  • useOptic: Logic-level effects with caching

  • useFlash: Post-render effects for animation

How Refract Compares

FeatureRefractReactSvelte
State ModelRefractionsHooks/StateStores
ReactivityAutomaticManual depsCompile-time
Logic ReuseOpticsHooksStores/Context

What’s Next?

Now that you understand the basics, jump into:

Ready to build better, reactive UIs?

Let’s get started!