Remix Booth
convention-driven full-stack production studio
Pro-grade state management. Zero compromises.
Rails conventions meet DJ mixing. Unmatched flexibility.
Master-level precision for your server/client state.
โจJSON Dynamics System๐
Brings JSON to life
No bloat, no overhead, just pure performance with a tiny footprint that won't slow down your application.
Create reactive derived state that updates automatically when dependencies change, with full TypeScript support.
Signal-based tracking for optimal performance, updating only what changed, with automatic dependency tracking.
Just use objects directly - no actions, reducers, or boilerplate to manage your state. Mutate and subscribe with ease.
Get serializable state snapshots on demand with json() - perfect for APIs, persistence, and time-travel debugging.
Inspect your state at any time, with built-in history tracking and time-travel debugging capabilities.
Simple. Reactive. Powerful.Edit the values below and see how jods reactively updates with the built-in reactive state system
import { store, json, computed, onUpdate } from "jods";
// Create a reactive store
const user = store({
firstName: "Burt",
lastName: "Macklin",
mood: "curious"
});
// Add computed property
user.fullName = computed(() =>
`${user.firstName} ${user.lastName}`
);
// Subscribe to changes
const unsubscribe = onUpdate(user, () => {
console.log("Store updated:", user.fullName);
// Update UI or trigger other actions
});
// Get a JSON snapshot at any time ๐ธ
console.log("๐ธ Snapshot:");
console.log(json(user));
JSON snapshot of your store from json(user)
. Updates automatically when values change.
Seamlessly integrate jods with React, Preact, and Remix using dedicated adapters
Seamless integration with React's component lifecycle
Lightweight integration for Preact applications
Specialized integration for Remix applications
import { store } from 'jods';
import { useJods } from 'jods/react';
const counter = store({ count: 0 });
function Counter() {
const state = useJods(counter);
return (
<button onClick={() => counter.count++}>
Count: {state.count}
</button>
);
}
๐Modern Data Layer for Remix:
reactive, type-safe, and persistence-ready
Server and client state without manual hydration
For optimistic UI updates
For runtime type validation and great DX
(Prisma, MongoDB, SQLite, etc.)
Based pattern across your entire application
// Traditional Remix Approach (without jods)
// loader.ts
export async function loader() {
const todos = await db.getTodos();
return json({ todos });
}
// action.ts
export async function action({ request }) {
const form = await request.formData();
const title = form.get("title");
await db.createTodo({ title });
return redirect("/todos");
}
// Component.tsx
function Todos() {
const { todos } = useLoaderData<typeof loader>();
return (
<div>
<h1>Todos ({todos.length})</h1>
<Form method="post">
<input name="title" placeholder="New todo..." />
<button type="submit">Add</button>
</Form>
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.title}
{todo.completed ? " โ" : ""}
</li>
))}
</ul>
</div>
);
}
// todos.jods.ts
import { j, defineStore } from "jods/remix";
// Define schema with Zod
const todoSchema = j.object({
id: j.string(),
title: j.string().min(1),
completed: j.boolean().default(false)
});
export const todos = defineStore({
name: "todos",
schema: j.object({
items: j.array(todoSchema)
}),
loader: async () => {
return { items: await db.getTodos() };
},
handlers: {
async addTodo({ current, form }) {
const title = form.get("title");
const newTodo = await db.createTodo({ title });
return {
...current,
items: [...current.items, newTodo]
};
}
}
});
// Export for route
export const loader = todos.loader;
export const action = todos.action;
// todos.tsx
import { todos } from "~/todos.jods";
import { useJods } from "jods/remix";
export default function TodosPage() {
// Type-safe access to your state and behavior
const { stores, actions, loaderData } = useJods(todos, "addTodo");
return (
<div>
<h1>Todos ({loaderData.items.length})</h1>
<ul>
{loaderData.items.map(todo => (
<li key={todo.id}>
{todo.title}
{todo.completed ? " โ" : ""}
</li>
))}
</ul>
{/* Form with automatic action integration */}
<actions.addTodo.Form>
<input name="title" placeholder="New todo..." />
<button type="submit">Add</button>
</actions.addTodo.Form>
</div>
);
}
Byte-sized brilliance โ compact code wielding cosmic-scale capabilities ๐
Feature | jods | Zustand | Redux | Preact Signals |
---|---|---|---|---|
๐ฆ Bundle Size | 1 KB | 3.4 KB | 16.4 KB + Redux Toolkit | 4.2 KB |
๐ Framework Dependency | ๐ฑ None | โ๏ธ React-only | ๐ Framework-agnostic | โก Preact-only |
๐ State Access | Proxied object (store.foo) | Hook (useStore) | Via selectors | Signal.value or JSX unwrap |
โ๏ธ Direct Mutations | โ | โ | ๐จโ๐ป (requires action creators) | signal.value = x |
๐งฎ Computed Values | ๐ง via computed() | ๐ง with selector functions | ๐ง (requires selectors) | โจ via computed() |
๐ธ JSON Snapshots | โ (built-in) | ๐ (manual) | โ (manual) | ๐ (manual) |
๐ Built-in diff | โ | ๐คท | ๐คท | ๐คท |
โฎ๏ธ Time-travel Debugging | โ | โ | โ | โฑ๏ธ |
๐ง Conceptual Simplicity | โ small mental model | โ (no actions/selectors) | ๐ง (complex patterns) | ๐ (steep learning curve) |
๐ฅ๏ธ Server Integration | ๐ฟ Remix | ๐ None | โ (manual) | ๐ None |