A lightweight, template-driven JavaScript framework for building dynamic web applications with minimal overhead.
Dynamo.js is a simple yet powerful framework that provides:
- Component-based architecture
- Template rendering with variable interpolation
- Conditional rendering and loops
- Two-way data binding
- AJAX interactions with declarative attributes
- Zero dependencies
Define reusable UI components that can be included in pages.
dynamo.component('componentName', `
<div>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
`);Create full page layouts with data binding.
dynamo.page('#app', `
{% include header %}
<main>
<h1>{{ pageTitle }}</h1>
</main>
{% include footer %}
`, {
pageTitle: 'Welcome',
// ... more data
});{{ variableName }}
{{ user.name }}
{{ product.price }}{% include componentName %}{% if showMessage %}
<p>{{ message }}</p>
{% endif %}Simple arrays:
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}Object arrays:
{% for city in cities %}
<li>
<a href="/city/{{ city.slug }}">{{ city.name }}</a>
</li>
{% endfor %}Bind input values to update other elements in real-time.
<input type="text" dy-model="username" placeholder="Enter name">
<p>Hello, <span dy-bind="username">Guest</span>!</p>dy-model: Binds input value to a state variabledy-bind: Updates element content when state changes
Make HTTP requests declaratively without writing fetch code.
<button dy-get="api/data.json"
dy-target="#results"
dy-swap="innerHTML">
Load Data
</button><form dy-post="api/submit"
dy-target="#response"
dy-swap="innerHTML">
<input name="email" type="email">
<button type="submit">Submit</button>
</form>dy-get: URL for GET requestdy-post: URL for POST requestdy-target: CSS selector for target element (default:body)dy-swap: How to insert content (default:innerHTML)
innerHTML: Replace target's contentouterHTML: Replace target element entirelybeforebegin: Insert before targetafterbegin: Insert at start of targetbeforeend: Insert at end of targetafterend: Insert after target
Register a reusable component.
Parameters:
name(string): Component identifiertemplate(string): HTML template with Dynamo syntax
Example:
dynamo.component('header', `
<header>
<h1>{{ siteName }}</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
`);Render a page with data.
Parameters:
selector(string): CSS selector for target elementtemplate(string): HTML template with Dynamo syntaxdata(object): Data object for template interpolation
Example:
dynamo.page('#app', `
{% include header %}
<main>
<h1>{{ title }}</h1>
{% for item in items %}
<p>{{ item }}</p>
{% endfor %}
</main>
`, {
title: 'My Page',
items: ['First', 'Second', 'Third']
});Re-render an existing element with new data.
Parameters:
selector(string): CSS selector for target elementdata(object): New data object
Example:
dynamo.render('#app', {
title: 'Updated Title',
items: ['New', 'Items']
});<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamo App</title>
</head>
<body>
<div id="app"></div>
<script src="dynamo.js"></script>
<script src="components.js"></script>
<script src="pages/home.js"></script>
</body>
</html>dynamo.component('header', `
<header>
<h1>{{ siteName }}</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
`);
dynamo.component('footer', `
<footer>
<p>© {{ year }} {{ siteName }}</p>
</footer>
`);dynamo.page('#app', `
{% include header %}
<main>
<h2>{{ title }}</h2>
<div>
<input type="text" dy-model="username" placeholder="Your name">
<p>Hello, <span dy-bind="username">Guest</span>!</p>
</div>
<button dy-get="api/items.json"
dy-target="#items"
dy-swap="innerHTML">
Load Items
</button>
<div id="items">
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</div>
{% if showMessage %}
<p>{{ message }}</p>
{% endif %}
</main>
{% include footer %}
`, {
siteName: 'My App',
year: new Date().getFullYear(),
title: 'Welcome',
items: ['Item 1', 'Item 2', 'Item 3'],
showMessage: true,
message: 'Hello from Dynamo!'
});- Component Organization: Keep components in a separate
components.jsfile - Page Structure: Organize pages in a
pages/directory - Data Separation: Pass data objects rather than hardcoding values
- Nested Properties: Use dot notation for nested data (
user.name,product.price) - Unique Selectors: Ensure
dy-targetselectors are unique to avoid conflicts - State Management: Use
dy-modelanddy-bindfor simple reactive updates
Dynamo.js uses modern JavaScript features:
- ES6+ syntax
- Fetch API
- Template literals
- Arrow functions
Supports all modern browsers (Chrome, Firefox, Safari, Edge).
- Minimize template complexity for faster rendering
- Use specific CSS selectors for better performance
- Avoid deeply nested loops when possible
- Cache component templates for reuse
- Use
dy-swapoptions strategically to minimize DOM updates
- No virtual DOM (direct DOM manipulation)
- Single-level nesting for object properties in loops
- No built-in routing (use server-side routing)
- No state management beyond simple binding
- Templates are processed once (not reactive by default)
MIT License - Free to use in personal and commercial projects.