GitHub - DmitryOlkhovoi/Ostov: Give your JS app a solid Ostov with Models, Views, Collections, and Events.

3 min read Original article ↗

Ostov.js

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

Ostovjs.org

Install

Or grab the file directly:

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.