Build reactive interfaces without surrendering HTML to a framework.
StrideJS keeps the browser model intact: ordinary HTML for the view, ordinary JavaScript for behavior, native platform APIs underneath. Add reactivity, forms, lists, shared state, events, fragments, routing, transitions, and a network pipeline with one zero-dependency ES module.
This is Stride state and binding, not a screenshot or simulated output.
Small enough to understand. Broad enough to build an application.
Stride is intentionally not a compiler, component language, or application platform. It supplies the browser-side plumbing that otherwise pushes many projects toward a much larger framework.
Deep object and array mutations update bound DOM, with synchronous writes batched into one render turn.
Proxy + microtaskBind text, attributes, classes, visibility, events, keyboard actions, and form controls without JSX.
s-*Repeat arrays, detach conditional subtrees, or keep a subtree mounted and simply toggle visibility.
s-loop / s-if / s-showTwo-way models, intercepted submissions, native constraint validation, and FormData payloads are built in.
s-model / s-submitShare reactive state globally, broadcast events between isolated roots, or include server-served HTML fragments.
store / on / includeUse history-based fragment routing and one interceptable fetch path for authentication, errors, and telemetry.
router / fetchThe HTML still explains the page when JavaScript is not open beside it.
No generated component syntax is required to understand where data appears or what user action invokes a method.
<div id="tasks" s-cloak>
<input s-model="newTask"
s-keyup:enter="addTask">
<button s-click="addTask">Add</button>
<ul>
<li s-loop="tasks">
<span s-text="item.name"></span>
</li>
</ul>
</div>
import Stride from 'https://cdn.stridejs.com/v1/stride.min.js';
Stride.create('#tasks', {
state: {
newTask: '',
tasks: []
},
methods: {
addTask() {
const name = this.state.newTask.trim();
if (!name) return;
this.state.tasks.push({ name });
this.state.newTask = '';
}
}
});
The useful part is not that the syntax is short. It is that Stride adds behavior while preserving familiar browser boundaries.
- Designers and backend-rendered templates can remain ordinary HTML.
- Application logic stays standard JavaScript instead of a template expression language.
- No required npm install, bundler, JSX transform, or virtual DOM runtime sits between the source and browser.
- A component can own one DOM island without forcing the rest of the application to adopt Stride.
Choose the smaller abstraction when the larger platform is not buying you anything.
React, Vue, Angular, and similar ecosystems solve broader problems and have much larger ecosystems. Stride targets the projects where those advantages are unnecessary overhead rather than pretending the tradeoff does not exist.
Stride is a strong fit for
- Server-rendered applications that need reactive islands.
- Admin panels, internal tools, dashboards, and control interfaces.
- Small and medium SPAs built from server-served HTML fragments.
- Existing sites that need incremental behavior without a frontend migration.
- Teams that deliberately want HTML + JavaScript without a required toolchain.
A larger framework may make more sense when you need
- A large third-party component ecosystem tied to one framework.
- Framework-specific SSR, hydration, server components, or meta-framework conventions.
- A mature framework plugin ecosystem as a primary architectural requirement.
- A team already standardized on a larger framework with no reason to introduce another runtime.
The documentation describes the full directive and JavaScript API, lifecycle behavior, router semantics, shared store, event bus, network interceptors, current boundaries, and cleanup behavior. The demo example workspace exercises the features together.