WEB-MOJO - A lightweight JavaScript framework for building data-driven web applications
npm install web-mojo

MOJO is a modern, lightweight JavaScript framework for building data-driven web applications. Built with a core + extensions architecture, MOJO provides maximum flexibility while maintaining clean boundaries and optimal performance.
šļø Core + Extensions Architecture - Clean separation with plugin system
š¦ Subpath Exports - Import exactly what you need
ā” Lazy Loading - Reduced bundle sizes with dynamic imports
š Plugin System - Extensions enhance core without dependencies
šÆ Tree Shaking - Optimized builds with modern bundlers
``bash`
npm install web-mojo
`javascript
// Core framework
import { WebApp, Page, View } from 'web-mojo';
// Create a simple page
class HomePage extends Page {
getTemplate() {
return '
// Initialize app
const app = new WebApp({
name: 'My App',
container: '#app'
});
app.registerPage('home', HomePage);
app.start();
`
MOJO 2.1.0 uses a core + extensions architecture:
#### š Authentication (web-mojo/auth)
Complete authentication system with JWT tokens:
`javascript
import { mountAuth } from 'web-mojo/auth';
// See docs/AuthPage.md for details.
mountAuth(document.getElementById('auth-root'), {
baseURL: 'https://api.example.com',
onSuccessRedirect: '/dashboard',
});
`
#### š¼ļø Lightbox (web-mojo/lightbox)
Image and PDF viewers with editing capabilities:
`javascript
import 'web-mojo/lightbox'; // Auto-registers plugins
// Core can now use lightbox features
import { Dialog } from 'web-mojo';
// Dialog automatically gets image cropping when lightbox is loaded
`
#### š Charts (web-mojo/charts)
Interactive charts built on Chart.js:
`javascript
import { PieChart, SeriesChart } from 'web-mojo/charts';
const chart = new PieChart({
data: salesData,
container: '#chart'
});
`
#### š Documentation (web-mojo/docit)
Documentation portal system:
`javascript
import { DocItApp } from 'web-mojo/docit';
const docs = new DocItApp({
books: ['user-guide', 'api-docs']
});
`
#### ā” Loader (web-mojo/loader)
Beautiful loading animations:
`html`
`javascript
import { PortalApp, Page } from 'web-mojo';
import 'web-mojo/lightbox'; // Enable image features
const app = new PortalApp({
name: 'Admin Portal',
sidebar: {
menus: [{
items: [
{ text: 'Dashboard', route: 'dashboard', icon: 'bi-speedometer2' },
{ text: 'Users', route: 'users', icon: 'bi-people' }
]
}]
}
});
class DashboardPage extends Page {
constructor(options = {}) {
super({
title: 'Dashboard',
template:
{{message}}
,
...options
});
}
async onActionShowDialog() {
const { Dialog } = await import('web-mojo');
Dialog.showInfo('Hello from MOJO!');
}
}
app.registerPage('dashboard', DashboardPage);
app.start();
`$3
`javascript
import { mountAuth } from 'web-mojo/auth';// Auth portal (standalone). See docs/AuthPage.md for details.
mountAuth(document.getElementById('auth-root'), {
baseURL: 'https://api.example.com',
onSuccessRedirect: '/portal/',
branding: {
title: 'Acme Corp',
logoUrl: '/assets/logo.png',
subtitle: 'Sign in to your account',
},
});
// Main app (after authentication)
const mainApp = new WebApp({
name: 'Acme Portal',
api: {
baseURL: 'https://api.example.com',
token: localStorage.getItem('auth_token')
}
});
// Handle successful login
authApp.events.on('auth:login', (user) => {
window.location.href = '/dashboard';
});
`$3
`javascript
import { Model, Collection, View } from 'web-mojo';// Define models
class User extends Model {
static endpoint = '/api/users';
}
class UserList extends Collection {
model = User;
endpoint = '/api/users';
}
// Create views
class UserTableView extends View {
constructor(options = {}) {
super({
template:
| Name | Actions | |
|---|---|---|
| {{name}} | {{email}} | data-action="edit-user" data-user-id="{{id}}">Edit |
,
...options
}); this.collection = new UserList();
}
async onMount() {
await this.collection.fetch();
this.render();
}
async onActionEditUser(action, event, element) {
const userId = element.dataset.userId;
const user = this.collection.get(userId);
const { Dialog } = await import('web-mojo');
Dialog.showModelForm(user, {
title: 'Edit User',
fields: ['name', 'email']
});
}
}
`š ļø Development
$3
`
web-mojo/
āāā src/
ā āāā index.js # Core entry point
ā āāā auth.js # Auth extension entry
ā āāā lightbox.js # Lightbox extension entry
ā āāā charts.js # Charts extension entry
ā āāā docit.js # DocIt extension entry
ā āāā loader.js # Loader entry
ā āāā core/ # Core framework
ā ā āāā View.js
ā ā āāā Page.js
ā ā āāā WebApp.js
ā ā āāā PortalApp.js
ā ā āāā models/
ā ā āāā views/
ā ā āāā services/
ā ā āāā utils/
ā āāā extensions/ # Extension packages
ā āāā auth/
ā āāā lightbox/
ā āāā charts/
ā āāā docit/
āāā examples/ # Live examples
āāā dist/ # Built packages
`$3
`bash
Install dependencies
npm installBuild all packages
npm run build:libDevelopment server
npm run devWatch mode
npm run dev:watch
`$3
When developing the framework itself:`javascript
// Use aliases for clean imports
import View from '@core/View.js';
import AuthApp from '@ext/auth/AuthApp.js';
import { PieChart } from '@ext/charts/PieChart.js';
`š API Reference
$3
Main application container with routing and page management.`javascript
const app = new WebApp({
name: 'My App', // App name
container: '#app', // DOM container
debug: true, // Debug mode
api: { // API configuration
baseURL: 'https://api.example.com',
token: 'jwt-token'
}
});// Register pages
app.registerPage('home', HomePage);
app.registerPage('users', UserListPage);
// Navigation
await app.navigate('users');
await app.navigate('user/123');
// Start app
await app.start();
`$3
Extended WebApp with built-in sidebar and top navigation.`javascript
const app = new PortalApp({
// All WebApp options plus:
sidebar: {
menus: [{
name: 'main',
items: [
{ text: 'Home', route: 'home', icon: 'bi-house' },
{
text: 'Admin',
icon: 'bi-gear',
children: [
{ text: 'Users', route: 'users' },
{ text: 'Settings', route: 'settings' }
]
}
]
}]
},
topbar: {
brand: 'My Portal',
rightItems: [
{ icon: 'bi-bell', action: 'notifications' }
]
}
});
`$3
`javascript
class MyView extends View {
constructor(options = {}) {
super({
className: 'my-view',
template: ,
...options
});
} // Lifecycle hooks
async onMount() { / Called when mounted to DOM / }
async onUnmount() { / Called when removed / }
// Event handlers
async onActionClickMe(action, event, element) {
this.showRegion('content', new AnotherView());
}
// Custom events
onCustomEvent(data) { / Handle custom events / }
}
`š§ Configuration
$3
For modern build tools:`javascript
// vite.config.js
export default {
optimizeDeps: {
exclude: ['web-mojo']
},
ssr: {
noExternal: ['web-mojo']
}
}
`$3
`javascript
// Bundle all CSS automatically
import 'web-mojo'; // Includes core CSS// Simple Auth CSS is included by the module (no extra import required).
// For theming details, see docs/AuthPage.md.
// If you need manual CSS, you can use: /src/extensions/auth/css/auth.css
import 'web-mojo/css/core';
import 'web-mojo/css/portal';
`š Migration from 2.0.x
$3
`javascript
// Old (2.0.x)
import WebApp from '/src/core/WebApp.js';
import AuthApp from '/src/auth/AuthApp.js';// New (2.1.0+)
import { WebApp } from 'web-mojo';
import { mountAuth } from 'web-mojo/auth'; // See docs/AuthPage.md
`$3
`html
`š¤ Contributing
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Make your changes following our coding standards
4. Add tests for new functionality
5. Commit your changes (git commit -m 'Add amazing feature')
6. Push to the branch (git push origin feature/amazing-feature)
7. Open a Pull Request$3
`bash
git clone https://github.com/yourusername/web-mojo.git
cd web-mojo
npm install
npm run dev
``This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- š Documentation: Full docs and examples
- š Issues: GitHub Issues
- š¬ Discussions: GitHub Discussions
---
Built with ā¤ļø by the MOJO Framework Team