@tmrw/core
v0.0.3
Published
A Refreshingly Simple JS Library for the Modern Web
Downloads
247
Readme
TomorrowJS
A Refreshingly Simple JS Library for the Modern Web
TomorrowJS is a lightweight, HTML-first JavaScript toolkit designed to help developers add dynamic behavior, data binding, and a touch of reactivity to their websites—without adopting a heavy, complex framework. Inspired by the elegance of libraries like jQuery and the intuitive data bindings of modern frameworks, TomorrowJS delivers just enough structure to make building interactive interfaces feel natural, fun, and powerful.
Goals & Philosophy of TomorrowJS
TomorrowJS was born from a desire to bridge the gap between bare-bones DOM scripting and heavyweight front-end frameworks. It aims to provide just enough structure and convenience to make building interactive, data-driven interfaces feel natural—without introducing a large mental model, complex abstractions, or heavy dependencies.
Core Principles:
1. Minimalism Over Complexity
TomorrowJS is intentionally small and straightforward. It avoids concepts like virtual DOMs, complex component systems, or proprietary templating languages. Instead, it focuses on enhancing standard HTML and JavaScript with minimal, intuitive utilities.
2. HTML-First
HTML stands at the core of TomorrowJS's approach. Rather than replacing the DOM or hiding it behind layers of abstraction, TomorrowJS augments the existing markup. Data binding and actions leverage attributes like data-t-*
to keep the interface declarative, simple, and aligned with native web standards.
3. Lean & Direct DOM Interactions
TomorrowJS embraces native browser APIs. Its $()
function and related methods are thin wrappers, not replacements. New features should remain close to the metal, using standard DOM methods under the hood. If a proposed feature requires introducing a heavy abstraction or deviates from simple DOM operations, it likely doesn't belong in TomorrowJS's core.
4. No Framework-Like Overhead
TomorrowJS is neither a framework nor a full client-side SPA solution. While it integrates easily into broader architectures or can be paired with SSR/SSG toolchains, its core should stay independent of larger ecosystems. It's a small toolkit, not a full ecosystem.
5. Simplicity in API & Usage
APIs should be consistent, guessable, and minimal. If a new method or feature can be expressed as a simple extension of existing patterns (like $().append()
, $().on()
, $().attr()
), it's worth considering. If it introduces new patterns or mental models, it may not fit.
6. Stable Boundaries & Scope
TomorrowJS focuses on:
- DOM selection and manipulation
- Data binding and store integration
- Simple event handling and actions
- Lightweight utilities for managing class, attributes, text, and HTML content
It intentionally avoids:
- A component model or proprietary template language
- State management beyond a simple store
- Routing, complex animations, or other specialized domains that can be handled by separate tools or plugins
This ensures TomorrowJS stays focused and doesn't drift into framework territory.
Contributing Guidelines:
Stay True to TomorrowJS's Philosophy
Before adding a feature, ask: Does this maintain TomorrowJS's simplicity and minimalism? Could it be done with a small utility or plugin outside the core?
Incremental & Familiar Enhancements
Proposals for new DOM methods or attribute-based capabilities should feel like a natural extension of TomorrowJS's existing APIs and patterns. Avoid forcing users to learn new concepts or paradigms.
Back to the DOM
If in doubt, remember TomorrowJS's essence: it's a thin layer over native web standards. If a feature can't be implemented simply via standard DOM operations and a sprinkling of data attributes, consider whether it belongs in TomorrowJS.
Resist Feature Creep
TomorrowJS's value lies in its small surface area. We prefer a few elegant, essential features over a large set of rarely used options. Quality and clarity over quantity.
By keeping these goals and boundaries in mind, contributors and maintainers ensure TomorrowJS remains the straightforward, minimal, and elegant toolkit that users rely on—and not just another complex framework.
Table of Contents
- Motivation & Problem Statement
- Key Features & Philosophy
- Getting Started
- Core Concepts
- DOM Utilities
- Events
- AJAX
- State Management
- Data Binding
- Actions
- Router (Optional)
- Plugin System
- Putting It All Together
- Integration & Extension
- FAQ & Comparisons
- License
Motivation & Problem Statement
Modern web development often falls into two extremes:
- Vanilla JavaScript: You have full control and no abstractions, but end up writing boilerplate code for DOM manipulation, event handling, and state updates. Projects quickly become repetitive and unwieldy.
- Frameworks & SPA Paradigms: React, Vue, Svelte, and others bring powerful concepts like components, virtual DOMs, and sophisticated reactivity. But with these benefits come complexity, build steps, a steeper learning curve, and sometimes a feeling of "overkill" for smaller projects.
The Problem
Many developers yearn for a middle ground—something simpler than a full SPA framework but more elegant than bare DOM scripting. A solution that lets them work primarily in HTML and progressively enhance the page, while still offering the convenience of data bindings, state management, and easy event handling.
The Goal
TomorrowJS aims to provide a refreshing alternative. It gives you a few well-chosen tools and patterns that align closely with native web standards, letting you build interactive interfaces without adopting a heavyweight mental model or complex tooling.
Key Features & Philosophy
- HTML-First: Use standard HTML as the foundation. With TomorrowJS, you enhance existing markup by adding attributes that describe what should happen—no special templates, no proprietary syntax.
- Lightweight & Minimalistic: TomorrowJS's code is small and focused. There's no virtual DOM, no build step required, and no hidden layers of complexity. It's a toolkit, not a full-blown framework.
- Intuitive Data Binding: Update the text of an element by changing a store value, and watch the DOM update automatically. Toggle classes based on state, and bind events via attributes—without complex directives.
- Simple State & Actions: A minimal store lets you track and update data. Named actions let you link DOM events to custom logic. By storing your application state in a simple object and registering actions, you get a straightforward reactivity pattern.
- Optional Router: Need some basic client-side routing? TomorrowJS includes a tiny optional router that updates a route key in your store. This lets you build multi-page-like experiences without a huge routing system.
Getting Started
No Build Steps Required: Just include TomorrowJS (via a <script>
tag or import it as an ES module). Start writing HTML and JavaScript the way you know, and enhance as needed.
Example Setup
<script type="module">
import { createStore, initTmrw } from '@tmrw/core';
const store = createStore({ title: 'Welcome to TomorrowJS!' });
initTmrw({ store, root: document.getElementById('app') });
</script>
<div id="app">
<h1 data-t-text="title"></h1>
</div>
Core Concepts
DOM Utilities
TomorrowJS's $
function provides a simple, chainable API inspired by jQuery, but modernized and minimal:
import { $ } from '@tmrw/core';
$('p.intro')
.addClass('highlight')
.on('click', () => console.log('Paragraph clicked!'));
The $
function provides many useful methods for DOM manipulation:
addClass
,removeClass
,toggleClass
: Manage CSS classeshtml
,text
: Get or set contenton
,off
: Event handlingattr
: Get or set attributescss
: Apply stylesappend
,prepend
: Add contentbefore
,after
: Insert adjacent contentremove
,empty
: Remove elements or their contentclone
: Create element copieswrap
: Wrap elements
Events
For event handling, TomorrowJS provides utilities to delegate events and trigger custom events easily:
onDelegate
: Attach a single event listener at a parent element that fires only when a child matching a selector is clicked.trigger
: Dispatch custom events.
AJAX
Use TomorrowJS's simple fetch wrappers for straightforward data retrieval:
import { getJSON, getText, postJSON } from '@tmrw/core';
getJSON('/api/data').then(data => {
console.log('Fetched data:', data);
});
State Management
TomorrowJS includes a tiny store system with subscription support:
import { createStore } from '@tmrw/core';
const store = createStore({ count: 0 });
// Subscribe to all changes
store.subscribe((key, value) => console.log(`${key} changed to:`, value));
// Update state
store.set('count', store.get('count') + 1);
// Unsubscribe when done
const unsubscribe = store.subscribe((key, value) => {
// Handle changes
});
unsubscribe(); // Remove subscription
Data Binding
TomorrowJS supports several data binding attributes:
data-t-text="key"
: Sets element text fromstore.get(key)
.data-t-html="key"
: Sets innerHTML fromstore.get(key)
.data-t-class="key:className"
: TogglesclassName
based on a boolean fromstore.get(key)
.data-t-attr="key:attrName"
: Dynamically updates the specified attribute (attrName
) to the value ofstore.get(key)
.
These bindings update automatically when the store changes. With strong TypeScript definitions, your editor can provide autocomplete and validation for store keys, reducing errors and improving clarity.
<h1 data-t-text="title"></h1>
<p data-t-text="description"></p>
Actions
Bind events to actions via data-t-on attributes:
<button data-t-on="click:incrementCount">Increment</button>
In JS:
import { registerAction } from '@tmrw/core';
registerAction('incrementCount', ({ store }) => {
if (store) store.set('count', (store.get('count') || 0) + 1);
});
Router (Optional)
For simple client-side navigation without heavy SPA frameworks, TomorrowJS includes a tiny router:
import { initRouter, navigate } from '@tmrw/core';
initRouter(store, { useHash: false });
navigate('/about'); // updates store's route key
Plugin System
TomorrowJS includes a plugin system for extending functionality:
import { use } from '@tmrw/core';
// Function-style plugin
use((ctx) => {
// Add new methods or modify existing ones
ctx.newMethod = () => { /* ... */ };
});
// Object-style plugin
use({
setup(ctx) {
// Plugin initialization code
ctx.pluginMethod = () => { /* ... */ };
}
});
Putting It All Together
A small example:
<div id="app">
<h1 data-t-text="title"></h1>
<p data-t-text="message"></p>
<button data-t-on="click:updateTitle">Change Title</button>
</div>
<script type="module">
import { createStore, registerAction, initTmrw } from '@tmrw/core';
const store = createStore({
title: 'Hello TomorrowJS',
message: 'Click the button to update the title.'
});
registerAction('updateTitle', ({ store }) => {
store.set('title', 'Title Updated!');
});
initTmrw({ store, root: document.getElementById('app') });
</script>
Integration & Extension
Server-Side Rendering: Render your initial HTML on the server. When the page loads, call initTmrw() to activate interactivity. TomorrowJS won’t replace your server framework; it works alongside it to provide a richer UI.
Custom Plugins: If you want extra features (like animations or more complex templating), add them as small extensions. TomorrowJS’s small surface area and straightforward architecture make it easy to integrate your own solutions without conflict.
Gradual Adoption: Start by just using $ and some event handling. Then add a store when you need dynamic state, data bindings for reactive UI, and finally actions and the router if your project grows. TomorrowJS scales gracefully from a small widget to a more interactive site.
FAQ & Comparisons
Q: Is TomorrowJS a framework? A: Not really. It’s more a collection of small, focused utilities that enhance vanilla web development patterns. Think of it as a toolkit or a set of building blocks, rather than a prescriptive framework.
Q: How is this different from jQuery? A: TomorrowJS uses modern DOM APIs, TypeScript, and adds concepts like data binding and a simple store—things jQuery never addressed. It also doesn’t rely on querySelectorAll replacements or older browser quirks. It’s a modern, minimal evolution.
Q: Doesn’t Vue/Svelte/etc. do more? A: Absolutely. TomorrowJS doesn’t try to be a fully featured SPA framework. Those tools are great for large, complex applications. TomorrowJS targets a space where developers want just a bit of dynamic behavior without fully embracing the complexity of a large framework. If you find frameworks heavy-handed, TomorrowJS might be refreshing.
Q: Can I use TomorrowJS with other libraries? A: Yes. TomorrowJS is modular and doesn’t impose strict architectural patterns. You can use it alongside other libraries or integrate it into existing projects without rewriting everything.
License
TomorrowJS is open-source and licensed under the MIT License, promoting freedom to adopt, customize, and distribute as you see fit.
By focusing on clarity, simplicity, and minimal overhead, TomorrowJS aims to empower developers to build dynamic, interactive interfaces without the cognitive weight of larger frameworks. It’s a breath of fresh air for those who believe that sometimes less is truly more.