π NEW in v0.6.0: Natural JavaScript syntax! No more
.set()
and.get()
- just write normal JavaScript and watch the magic happen. See what's new β
What if changing one value in your JavaScript object automatically updated everything that depends on it?
Like Excel, but for your app's data. No frameworks, no build tools, no configuration. Just reactive magic.
// Your shopping cart updates itself automatically
const cart = new Glue({ items: [], total: 0 });
// When items change, total recalculates instantly
cart.addObserver('items', () => {
cart.total = cart.items.reduce((sum, item) => sum + item.price, 0);
});
cart.items.push({ name: 'Coffee', price: 5 });
console.log(cart.total); // 5 - calculated automatically!
That's it. Just normal JavaScript. No .set()
, no .push()
, no learning curve. Just reactive data that works like magic.
Because managing state sucks. You've been there:
// The old way: Manual updates everywhere π©
function updateCart() {
const items = getItems();
const subtotal = calculateSubtotal(items);
const tax = calculateTax(subtotal);
const shipping = calculateShipping(subtotal);
const total = subtotal + tax + shipping;
updateSubtotalDisplay(subtotal);
updateTaxDisplay(tax);
updateShippingDisplay(shipping);
updateTotalDisplay(total);
updateCartBadge(items.length);
// Oh wait, forgot to update the checkout button state...
// And the recommendations engine...
// And the analytics event...
}
With glue.js: Everything just updates automatically π―
const cart = new Glue({ items: [], subtotal: 0, tax: 0, total: 0 });
// Set up the magic once
cart.addObserver('items', updateSubtotal);
cart.addObserver('subtotal', updateTax);
cart.addObserver('subtotal', updateTotal);
cart.addObserver('tax', updateTotal);
// Now just change data - everything else happens automatically
cart.items.push({ name: 'iPhone', price: 999 });
// β¨ Subtotal, tax, and total all update instantly
const form = new Glue({ email: '', password: '', errors: {} });
form.addObserver('email', () => {
if (!form.email.includes('@')) {
form.errors.email = 'Please enter a valid email';
} else {
delete form.errors.email;
}
});
// Type in email field β validation happens instantly
// No more managing validation state manually!
Watch nested properties, array changes, even calculated values:
const dashboard = new Glue({
company: {
users: [
{ name: 'Alice', profile: { active: true, tier: 'premium' }, spending: { total: 1200 } },
{ name: 'Bob', profile: { active: false, tier: 'basic' }, spending: { total: 450 } }
],
metrics: {
activeUsers: 0,
premiumUsers: 0,
revenue: 0,
averageSpend: 0
}
}
});
// Watch deep nested changes - this is the magic! β¨
dashboard.addObserver('company.users', () => {
console.log('Users array changed!');
updateMetrics();
});
// Watch individual user properties
dashboard.addObserver('company.users[0].profile.active', updateMetrics);
dashboard.addObserver('company.users[1].profile.active', updateMetrics);
dashboard.addObserver('company.users[0].spending.total', updateMetrics);
dashboard.addObserver('company.users[1].spending.total', updateMetrics);
// Or use generic array observation (watches ALL array elements)
dashboard.addObserver('company.users[]', updateMetrics);
// Watch calculated values change automatically
dashboard.addObserver('company.metrics.activeUsers', () => {
dashboard.company.metrics.averageSpend =
dashboard.company.metrics.revenue / dashboard.company.metrics.activeUsers;
});
function updateMetrics() {
const users = dashboard.company.users;
dashboard.company.metrics.activeUsers = users.filter(u => u.profile.active).length;
dashboard.company.metrics.premiumUsers = users.filter(u => u.profile.tier === 'premium').length;
dashboard.company.metrics.revenue = users.reduce((sum, u) => sum + u.spending.total, 0);
}
// Now watch the cascade! Change one deep value, everything updates:
dashboard.company.users[0].profile.active = false;
// β User activation observer fires
// β updateMetrics() runs
// β activeUsers changes
// β averageSpend observer fires
// β averageSpend recalculates automatically
// Even array operations trigger deep observation:
dashboard.company.users.push({
name: 'Charlie',
profile: { active: true, tier: 'premium' },
spending: { total: 2000 }
});
// β All metrics recalculate automatically!
This is where glue.js gets truly magical - watch calculated values change other calculated values:
const ecommerce = new Glue({
cart: {
items: [
{ name: 'Widget', price: 9.99, quantity: 2 },
{ name: 'Gadget', price: 15.50, quantity: 1 }
]
},
pricing: {
subtotal: 0,
discountPercent: 0.1,
discount: 0,
tax: 0,
shipping: 0,
total: 0
}
});
// Set up the calculation cascade
ecommerce.addObserver('cart.items', updateSubtotal);
ecommerce.addObserver('cart.items[]', updateSubtotal); // Watch any array element changes!
ecommerce.addObserver('pricing.subtotal', updateDiscount);
ecommerce.addObserver('pricing.discountPercent', updateDiscount);
ecommerce.addObserver('pricing.subtotal', updateShipping);
ecommerce.addObserver('pricing.discount', updateShipping);
ecommerce.addObserver('pricing.subtotal', updateTax);
ecommerce.addObserver('pricing.discount', updateTax);
// Watch ALL the calculated values to update total
ecommerce.addObserver('pricing.subtotal', updateTotal);
ecommerce.addObserver('pricing.discount', updateTotal);
ecommerce.addObserver('pricing.tax', updateTotal);
ecommerce.addObserver('pricing.shipping', updateTotal);
function updateSubtotal() {
ecommerce.pricing.subtotal = ecommerce.cart.items
.reduce((sum, item) => sum + (item.price * item.quantity), 0);
}
function updateDiscount() {
ecommerce.pricing.discount = ecommerce.pricing.subtotal * ecommerce.pricing.discountPercent;
}
function updateShipping() {
const afterDiscount = ecommerce.pricing.subtotal - ecommerce.pricing.discount;
ecommerce.pricing.shipping = afterDiscount > 50 ? 0 : 5.99;
}
function updateTax() {
const taxable = ecommerce.pricing.subtotal - ecommerce.pricing.discount;
ecommerce.pricing.tax = taxable * 0.08;
}
function updateTotal() {
ecommerce.pricing.total = ecommerce.pricing.subtotal
- ecommerce.pricing.discount
+ ecommerce.pricing.shipping
+ ecommerce.pricing.tax;
}
// Initialize
updateSubtotal();
// Now watch the magic! One small change cascades through everything:
ecommerce.cart.items[0].quantity = 3;
// β subtotal changes (9.99 * 3 + 15.50 = 45.47)
// β discount changes (45.47 * 0.1 = 4.55)
// β shipping changes (40.92 < 50, so shipping = 5.99)
// β tax changes ((45.47 - 4.55) * 0.08 = 3.27)
// β total changes (45.47 - 4.55 + 5.99 + 3.27 = 50.18)
// All automatically! π€―
// Even changing discount percent cascades everything:
ecommerce.pricing.discountPercent = 0.15;
// β discount recalculates
// β shipping recalculates
// β tax recalculates
// β total recalculates
// Like a spreadsheet, but in JavaScript!
Most libraries make you manage dependencies manually:
// Redux/MobX style: You have to remember what depends on what
function updateCart() {
updateSubtotal(); // Did you remember this?
updateDiscount(); // What about this?
updateShipping(); // And this?
updateTax(); // Easy to forget!
updateTotal(); // Order matters!
}
glue.js makes dependencies self-managing:
// Just declare what depends on what, then forget about it
ecommerce.addObserver('pricing.subtotal', updateDiscount);
ecommerce.addObserver('pricing.subtotal', updateShipping);
ecommerce.addObserver('pricing.subtotal', updateTax);
// Now ANY change to subtotal automatically updates everything
// No manual coordination, no forgetting dependencies, no bugs! π―
The result? Your code becomes self-healing. Add new calculated values, change existing ones, refactor business logic - the dependency graph automatically stays correct.
npm install @felixflores/glue.js
const Glue = require('@felixflores/glue.js');
const data = new Glue({ count: 0, doubled: 0 });
// When count changes, doubled updates automatically
data.addObserver('count', () => {
data.doubled = data.count * 2;
});
data.count = 5;
console.log(data.doubled); // 10 β¨
That's literally it. No webpack, no babel, no configuration. Just reactive data.
glue.js now uses natural JavaScript syntax that feels like native language features:
// β¨ Modern (v0.6.0+): Just write normal JavaScript
const data = new Glue({ user: { name: 'Alice', age: 25 } });
data.user.name = 'Bob'; // β Triggers observers automatically
data.user.age += 1; // β So does this
data.items.push(newItem); // β And this
delete data.user.oldProp; // β Even this!
// π Legacy (still works): Traditional API
data.set('user.name', 'Bob');
data.set('user.age', data.get('user.age') + 1);
data.push('items', newItem);
data.remove('user.oldProp');
How it works: glue.js automatically detects modern JavaScript environments and uses Proxy to intercept property changes. In older environments, it gracefully falls back to traditional methods.
Best part: Your code is 100% backward compatible. Existing apps keep working, but you can start using the natural syntax immediately.
Before v0.6.0 - Had to use manipulator functions:
dashboard.set('activeUsers', users.filter(u => u.active).length);
dashboard.set('revenue', calculateRevenue(dashboard.get('users')));
After v0.6.0 - Just write JavaScript:
dashboard.activeUsers = users.filter(u => u.active).length;
dashboard.revenue = calculateRevenue(dashboard.users);
Same powerful reactivity, zero learning curve. π―
- π― Natural JavaScript syntax - Just
obj.prop = value
, no learning curve - π Automatic fallback - Uses modern Proxies when available, traditional methods otherwise
- π¦ Zero dependencies - No bloat, no security vulnerabilities, no version conflicts
- β‘ Tiny footprint - Less than 10KB, works everywhere (even IE11)
- π οΈ Zero configuration - No build tools, no setup, no framework lock-in
- π§ Actually simple - If you understand
addEventListener
, you understand glue.js - π Production proven - Running in production apps for over a decade
Perfect for:
- Complex calculated values - Spreadsheet-like dependency chains
- Deep object observation - Watch nested properties and array changes
- Real-time dashboards - Metrics that depend on other metrics
- E-commerce pricing - Discounts, tax, shipping calculations
- Form validation - Field interdependencies and business rules
- Game state management - Scores, levels, achievements that cascade
- Financial applications - Interest, fees, balances that auto-update
- Data visualization - Charts that respond to deep data changes
- Any time you think "this is like Excel" - That's exactly what glue.js does!
Maybe overkill for:
- Static websites with no interactivity
- Simple CRUD with no calculated fields
- Hello world apps
- One-off scripts that don't need reactivity
- Complete API Documentation - Every method, parameter, and option
- Advanced Patterns - Deep dives, best practices, and complex examples
- Migration Guide - Upgrading from older versions
- Performance Guide - Benchmarks and optimization tips
Found a bug? Have an idea? We'd love your help!
- Report issues - Bug reports and feature requests
- Submit PRs - Code improvements and fixes
- Improve docs - Help make the docs clearer
- Share examples - Show us what you built!
Quick dev setup:
git clone https://github.com/felixflores/glue.js
cd glue.js
npm install
npm test
Made with β€οΈ by developers who got tired of state management complexity.
Star us on GitHub if glue.js makes your life easier! β