A modern reimagining of Backbone.js — same proven MVC patterns, no jQuery, no Underscore, ships as a native ES module.
- Zero hard dependencies (includes a minimal built-in utility layer)
- Native ES module — works in browsers and any bundler (Vite, Rollup, webpack 5+)
- Full TypeScript types included
- Familiar Backbone API — drop-in for most use cases
Docs
Install
Or grab the file directly:
- ostov.js — development build
- ostov.min.js — production build
Usage
npm / bundler
import { Model, Collection, View, Router, Events } from 'ostovjs';
Or import the full namespace:
import Ostov from 'ostovjs';
Browser — ES module
<script type="module"> import { Model, Collection } from './ostov.js'; </script>
Browser — classic script tag
<script src="ostov.js"></script> <!-- Ostov is now available as a global variable -->
✨ Why Ostov?
Backbone had a great core idea:
- explicit state (models)
- event-driven updates
- separation of concerns
Ostov keeps that — but removes legacy baggage:
- ❌ no jQuery
- ❌ no Underscore
- ✅ ES modules
- ✅ ES classes
- ✅ TypeScript generics
🚀 TypeScript + Classes
Model
import { Model } from 'ostovjs'; interface TodoAttrs { title: string; completed: boolean; } export class Todo extends Model<TodoAttrs> { defaults() { return { title: '', completed: false, }; } toggle() { this.set('completed', !this.get('completed')); } }
Collection
import { Collection } from 'ostovjs'; import { Todo } from './Todo'; export class TodoList extends Collection<Todo> { model = Todo; completed() { return this.where({ completed: true }); } }
View (class-based)
import { View } from 'ostovjs'; import { Todo } from './Todo'; export class TodoView extends View<Todo> { events() { return { 'click [data-action="toggle"]': 'onToggle', }; } initialize() { this.listenTo(this.model, 'change', this.render); } render() { this.el.innerHTML = ` <button data-action="toggle">Toggle</button> <span>${this.model.get('title')}</span> `; return this; } onToggle() { this.model.toggle(); } }
🧩 Using Handlebars (templating)
Ostov does not force a templating system — you can plug in anything.
Example with Handlebars:
import Handlebars from 'handlebars'; import { View } from 'ostovjs'; const template = Handlebars.compile(` <div> <h3>{{title}}</h3> <button data-action="toggle"> {{#if completed}}Undo{{else}}Complete{{/if}} </button> </div> `); export class TodoView extends View { initialize() { this.listenTo(this.model, 'change', this.render); } render() { this.el.innerHTML = template(this.model.toJSON()); return this; } }
👉 You can use any templating engine:
- Handlebars
- Mustache
- JSX (custom)
- plain strings
🔁 Backbone-style .extend(...)
Ostov still supports classic Backbone patterns:
import { Model, View } from 'ostovjs'; const Todo = Model.extend({ defaults: { title: '', completed: false, }, toggle() { this.set('completed', !this.get('completed')); }, }); const TodoView = View.extend({ events: { 'click button': 'toggle', }, initialize() { this.listenTo(this.model, 'change', this.render); }, render() { this.el.innerHTML = this.model.get('title'); return this; }, toggle() { this.model.toggle(); }, });
👉 This is useful if:
- you're migrating from Backbone
- you prefer prototype-style inheritance
🆚 Modern vs Legacy usage
| Style | Use |
|---|---|
| Classes + TS | ✅ recommended |
.extend(...) |
✅ supported |
| Templates | any (no lock-in) |
🧠 Core Idea
Ostov gives you primitives:
- Model
- Collection
- View
- Router
- Events
No magic. Just structure.
🎯 When to use
- small / medium apps
- dashboards
- internal tools
- apps where React feels like overkill
🚫 When not to use
- heavy ecosystem requirements
- large teams needing strict conventions
⭐ Support
If you like Backbone-style architecture with modern TypeScript —
drop a star ⭐
🧨 Philosophy
Less framework. More control.
Built with Ostov
TLDR extension for google chrome — Get a TLDR summary of any page using OpenAI. Ask follow-up questions in a dedicated tab.