Table of contents
Why Valyrian.js
One application, in the browser and Node.js.
Build one Valyrian.js application with components, state, routing, data and forms. When the application needs SSR, Node.js imports and executes that same application instead of requiring a server-specific version.
Write close to HTML and native JavaScript. Build declaratively, then follow the same application from browser interaction to server rendering and back to browser hydration.
Start the Taskboard · Explore the guides
The same application runs in the browser and Node.js
A Valyrian.js application does not need a second component tree or router for SSR. The Node.js backend imports the application already used by the browser.
Browser and Node.js import the same application. Its components, routes, state owners, requests and rendering logic remain in the shared source. Use isNodeJs when that source needs to select browser-only or Node.js-only behavior.
Node.js renders the application to HTML, and the browser mounts that same application to hydrate the existing DOM and connect its interactions.
More capabilities, fewer moving parts
Valyrian.js keeps essential application capabilities in code that can run in the browser and Node.js.
Routing, data, state, forms and offline support extend the browser application. Node.js executes that same application for SSR without introducing a second component or routing architecture.
That integration reduces assembly decisions and the number of rules a team needs to maintain. Each new capability extends the existing model instead of replacing it.
The rendering model remains close to HTML and JavaScript while supporting declarative interfaces and efficient updates. Valyrian.js covers more needs without distributing application logic across disconnected models.
From interaction to rendering
Valyrian.js keeps interactions, state changes, asynchronous operations, and rendering visible in the code. Each interaction has an identifiable entry point, and every update preserves a path that can be inspected.
A new developer can trace an event to the interface without first learning a hidden execution model. An experienced developer can inspect that path, shape the architecture, and extend the system through explicit modules.
Clear ownership and named operations reduce implicit behavior. Intent can be traced across components, state, server work, and rendering without reconstructing hidden rules or relying on invisible framework magic.
That predictability makes the application easier to understand, debug, and extend as it grows.
State you can reason about
Pulses bring together ideas from mutations, actions, producers, and reactive signals, then turn them into a model native to Valyrian.js.
They can mutate state, coordinate asynchronous work, and provide fine-grained reactivity. State can be modified directly and safely, without cloning it or returning a replacement after every operation, and only affected dependencies receive the update.
Inside PulseStore, Pulses unite those responsibilities around named operations and shared reactive state. Every change has an identifiable origin, and its effects can be traced to the parts of the interface that depend on it.
Mutation, asynchronous action, producer-style modification, and fine-grained updates become parts of one explicit flow. The result is a state model that is direct to write and clear to read.
Grow without fragmentation
What you learn while building the first component remains useful when you add routes, data, forms, SSR, and offline support.
Router connects screens. Request and Query carry data work. Suspense gives asynchronous interfaces a visible structure. FormStore brings state and validation together. Node.js can then import that complete application for server rendering, and the browser can hydrate its HTML before adding offline queues and service worker behavior.
Each stage adds capabilities without asking you to relearn how the system is organized. The initial concepts remain in place, and the architecture keeps a recognizable shape.
Valyrian.js gives new developers a clear way in, experienced developers room to shape the system, and a codebase whose behavior can be traced from beginning to end.
Build the application
Taskboard proves this architecture one stage at a time. Build the application in the browser, import the same application into Node.js for SSR, hydrate its HTML in the browser and continue with offline and PWA behavior.
Start the Taskboard · Explore Valyrian.js guides
Acknowledgements
- Hyperapp, for being the original spark behind Valyrian.js and its direct, functional approach.
- Inferno, for raising the performance standard of the Virtual DOM and demonstrating that it could compete with code-generating approaches.
- Vue and Vuex, for declarative interfaces and the action and mutation model that inspired PulseStore.
- Immer, for the ergonomics of safe producer-style mutation reflected in PulseStore.
- Solid, for advancing signal-based fine-grained reactivity, an inspiration for Pulses and PulseStore.
- Flux and Redux, for establishing explicit, predictable flows for application state.
- React, for the component and JSX ecosystem that advanced the tools, libraries, knowledge, and community of web development.
Valyrian.js carries this lineage into an architecture of its own.