create-gardener
v2.1.9
Published
A dom gardener converting dom elements into json and vice versa
Maintainers
Readme
🌱 Gardener
Gardener is a lightweight, DOM-first front-end library for building and manipulating HTML/SVG elements using a clean, declarative JavaScript object syntax.
No virtual DOM. No JSX. No compilation step. No magic.
Everything is explicit and inspectable directly in the browser.
Version: 2.0.0
- lsp support on frontend
- separate files for js logic inside /static/pages/(filename)
- bug fixes in application and scripts
✨ Philosophy
Gardener follows a DOM-first, deterministic approach:
- No Virtual DOM
- No JSX
- No compilation / bundler required
- No runtime abstraction layers
- Everything renders directly to the real DOM
- Works natively in the browser (ES modules)
If you can inspect it in DevTools, you can understand it.
🚀 Features
- Declarative object-based DOM creation
- Automatic SVG namespace handling
- Development server support
- Hot Reload (dev mode)
- HTML → Component parser
- Dynamic image resizing & caching
- Static site generation
- Lightweight reactive
Statesystem - Zero build step required
📦 Installation
Simply include the module:
<script type="module" src="/gardener.js"></script>No bundler required.
🌿 Core API
1️⃣ gardener() — Declarative Element Builder
gardener({
t: 'div',
cn: ['p-6', 'flex', 'gap-4'],
attr: { id: 'hero', role: 'banner' },
txt: 'Welcome',
events: {
click: () => console.log('clicked!')
},
children: [
{ t: 'span', txt: 'Nested child' }
]
})Supported Keys
| Key | Description |
| ---------- | -------------------------------- |
| t | Tag name (HTML or SVG) |
| cn | Array of class names |
| attr | Attributes / properties object |
| txt | Text content |
| events | { eventName: handler } |
| children | Array of nested gardener objects |
2️⃣ DOM Helpers
fetchElement(selector)
appendElement(parent, child)
replaceElement(oldElement, newElement)
createElement(type, classes)
insertText(element, text)
addEL(parent, event, handler)Example:
const el = gardener({ t: 'h1', txt: 'Hello' });
appendElement('body', el);🔄 SVG Support
Gardener automatically uses the correct SVG namespace for:
svg, path, circle, rect, line, polygon, polyline, g, defs, clipPath, useExample:
gardener({
t: 'svg',
attr: { width: 100, height: 100 },
children: [
{ t: 'circle', attr: { cx: 50, cy: 50, r: 40, fill: 'red' } }
]
})🧠 State Management
A minimal reactive system.
const count = new State(0);
count.registerCb(value => {
console.log("New value:", value);
});
count.setTo(1);API
new State(initialValue).registerCb(callback).setTo(newValue)
No proxies. No diffing. Just callbacks.
🔥 Development Mode
Configure runtime behavior:
const config = {
mode: 'dev', // 'dev' | 'prod'
componentdir: 'static/components',
hotreload: false
}Dev Mode Includes:
- Floating "+" page creator
- Component parser
- Hot reload toggle
- Static site builder
♻️ Hot Reload
- State stored in
localStorage - Reloads page ~1 second after change
- Toggle with:
Alt + HOr use the built-in checkbox (dev mode only).
🧩 Component Parser
Turn existing HTML into reusable JS components.
Step 1 — Write HTML
<div id="user-card">
Hello, ?name?
</div>Step 2 — Run in console
parser('#user-card')Step 3 — Generated File
export default function thisfun({ name }) {
return gardener({
t: "div",
txt: "Hello, " + name
})
}🧾 Parameter Syntax
Use:
?variable?Gardener extracts variables and generates a function with those parameters.
🖼 Image Optimization
Place originals in:
/src/frontend/assets/Use:
<img src="/static/cache/photo_800x600.webp">Server will:
- Resize
- Convert to WebP
- Cache automatically
📄 Create New Pages (Dev Mode)
- Click floating
+ - Enter route (e.g.,
/about) - Page auto-generated
- Browser redirects
Template used:
/src/backend/frontendtemplate.ejs🏗 Static Site Generation
Visit:
/createstaticBuild output:
/src/frontendStatic🧩 How It Works
Gardener:
- Converts object → real DOM
- Applies attributes safely
- Handles properties vs attributes
- Recursively renders children
- Avoids virtual DOM entirely
The browser is the rendering engine.
🎯 When To Use Gardener
Good for:
- Lightweight SPAs
- Internal tools
- Static + hybrid sites
- Dev tooling
- Projects where you want full DOM control
- No-build-step environments
Not designed to replace React/Vue — designed to avoid them when unnecessary.
🛠 Example App
import { gardener, appendElement } from './gardener.js';
const app = gardener({
t: 'div',
cn: ['app'],
children: [
{ t: 'h1', txt: 'Hello World' },
{
t: 'button',
txt: 'Click Me',
events: {
click: () => alert('Hi!')
}
}
]
});
appendElement('body', app);📁 Project Structure (Suggested)
/src
/frontend
/backend
/frontendStatic
/static
/components
gardener.js🧭 Roadmap Ideas
- Fine-grained reactive bindings
- Dev inspector panel
- Server-side rendering mode
- Plugin API
- Optional diff mode
📜 License
MIT (recommended)
🌿 Why Gardener?
Because sometimes you don't need a forest.
Just a garden.
