Bau.js is a JavaScript library for building reactive web user interfaces in under 350 lines of code, with no JSX, no templating, no virtual DOM, and no compiler.
What is Bau.js?
Bau.js is a reactive UI library that renders components written as plain JavaScript functions into real DOM nodes. The library takes state objects and component functions as inputs and outputs live DOM that updates automatically when the state mutates. It runs in any modern browser and integrates with Astro for server-side rendering through the bau-astro package. Bau.js is maintained by GruCloud and is published on npm as @grucloud/bau.
Key Features
- Minimal core — The entire library fits in under 350 lines of JavaScript, with a public API consisting of just
tags, state, loop, and derive.
- Proxy-based reactivity — Data mutations are intercepted via JavaScript proxies, so when a state value changes, every DOM node bound to that value is updated in place.
- No JSX or virtual DOM — Components are functions that return real DOM elements; the library avoids the JSX transform and virtual DOM diffing entirely.
- State supports arrays and objects — Unlike some reactive libraries that only handle primitives, Bau's
state can manage arrays and objects, enabling complex data structures.
- Lifecycle hooks — Components can use
bauCreated, bauMounted, and bauUnmounted to run code at creation, after insertion into the DOM, and before removal.
- TypeScript definitions — The ecosystem ships TypeScript declaration files for typed code completion in editors like VS Code.
- Companion libraries — Bau ships with bau-css (a 33-line CSS-in-JS solution), bau-ui (50+ themable components), bau-router (nested routes, async loading, under 0.6 kB), bau-kit (a 5 kB multi-page app starter), bausaurus (a Markdown static site generator), and bau-astro (Astro integration).
Who is it for?
- Vanilla JavaScript developers who want reactive UI without learning JSX or a virtual DOM framework can write components using everyday JavaScript functions and DOM methods.
- Bundle-size-conscious teams building simple to medium SPAs can use bau-kit to ship an app in under 5 kB, roughly 20 times smaller than a React/Redux/React Router/Styled Components combination.
- Astro users who need client-side reactivity can use bau-astro to leverage Astro's SSR while keeping interactive islands small.
- Developers comparing reactive libraries can benchmark Bau against others via the js-framework-benchmark project, where it scores well on most tests.
What can you do with Bau.js?
- Build interactive components: Create a counter with a state integer and buttons that mutate it; the displayed value updates automatically without manual DOM manipulation.
- Assemble a full application: Use bau-kit as a starting point for a multi-page app, combining state, routing, CSS, and components within a single small bundle.
- Generate static sites: Use bausaurus to convert Markdown content into a static website while keeping Bau components for interactivity.
- Add reactivity to Astro: With bau-astro, you can render Bau components on the server and hydrate them client-side, matching Astro's islands architecture.
How does Bau.js work?
You create a state object with bau.state(initialValue), define a component as a function that returns a DOM node tree built from bau.tags (like button, span, etc.), and then replaceChildren the result into a container. When an event handler mutates the state (e.g., incrementing counter.val), the proxy triggers a targeted DOM update for every node depending on that value.
Alternatives
- Van.js — A similar tiny reactive library that inspired Bau; it only supports primitive values as state, while Bau also supports arrays and objects, lifecycle methods, and avoids a global variable by allowing multiple Bau instances.
- React — A widely used UI library with JSX and a virtual DOM; Bau offers a smaller footprint and no build step for its core, but React has a larger ecosystem.
FAQ
Does Bau.js use JSX or a virtual DOM?
No. Bau.js uses plain JavaScript functions that return real DOM nodes. There is no JSX syntax to compile and no virtual DOM diffing; updates go directly to the live DOM via proxy-intercepted state mutations.
What is the bundle size of Bau.js?
The core library is under 350 lines of code. The bau-kit starter packs routing, state, CSS, and components into under 5 kB. bau-router alone is under 0.6 kB, and bau-css is only 33 lines.
Does Bau support TypeScript?
Yes. The Bau ecosystem exports TypeScript definition files, giving developers type inference and autocompletion in IDEs like VS Code.
How does Bau compare to Van.js?
Bau was inspired by Van.js. The key differences are: Bau state can hold arrays and objects while Van only handles primitives; Bau provides lifecycle hooks (bauCreated, bauMounted, bauUnmounted); Bau does not rely on a global variable, so multiple instances can coexist; and Bau prevents mixing imperative and reactive paradigms.
Can Bau be used with Astro?
Yes, through the bau-astro integration. It allows you to use Bau components in Astro projects and take advantage of Astro's server-side rendering, with hydration on the client side.
