dd<el> Comprehensive Reference
This reference guide provides a comprehensive summary of dd<el>’s key concepts, best practices, case studies, and advanced techniques. Use it as a quick reference when working with the library or to deepen your understanding of its design principles and patterns.
# Core Principles of dd<el>
At its foundation, dd<el> is built on several core principles that shape its design and usage:
Guiding Principles
- DOM-First Approach: Working directly with the real DOM instead of virtual DOM abstractions
- Declarative Syntax: Creating UIs by describing what they should look like, not how to create them
- Minimal Overhead: Staying close to standard Web APIs without unnecessary abstractions
- Progressive Enhancement: Starting simple and adding complexity only when needed
- Flexibility: Using what you need, whether that’s plain DOM elements, event handling, or signals for reactivity
- Functional Composition: Building UIs through function composition
- Clear Patterns: Promoting maintainable code organization with the 3PS pattern
- Targeted Reactivity: Using signals for efficient, fine-grained updates only when needed
- Unix Philosophy: Doing one thing well and allowing composability with other tools
# Case Studies & Real-World Applications
Explore our Examples Gallery to see how dd<el> can be used to build various real-world applications, from simple components to complex interactive UIs.
TodoMVC Implementation
The TodoMVC implementation showcases how dd<el> handles a complete, real-world application with all standard features of a modern web app:
- Persistent storage with localStorage
- Reactive UI with automatic updates
- Client-side routing with hash-based URLs
- Component-based architecture
- Performance optimization with memoization
- Custom event system for component communication
- Proper focus management and accessibility
Key takeaways from the TodoMVC example:
- Signal factories like
routerSignal
andtodosSignal
encapsulate related functionality - Custom events provide clean communication between components
- Targeted memoization improves rendering performance dramatically
- Derived signals simplify complex UI logic like filtering
Migrating from Traditional Approaches
When migrating from traditional DOM manipulation or other frameworks to dd<el>:
- Start with state: Convert global variables or ad-hoc state to signals
- Replace query selectors: Replace getElementById/querySelector with direct references to elements
- Convert imperative updates: Replace manual DOM updates with declarative signal bindings
- Refactor into components: Organize related UI elements into component functions
// Before: Imperative DOM updates
function updateUI() {
document.getElementById('counter').textContent = count;
document.getElementById('status').className = count > 10 ? 'warning' : '';
}
// After: Declarative with dd<el>
const countS = S(0);
el("div").append(
el("span", { id: "counter", textContent: countS }),
el("div", {
id: "status",
className: S(() => countS.get() > 10 ? 'warning' : '')
})
);
# Key Concepts Reference
Elements & DOM Creation
- el(tag|component, props, ...addons)
- Core function for creating DOM elements with declarative properties
- el().append(...children)
- Add child elements to a parent element
- memo(key, () => element)
- Cache and reuse DOM elements for performance optimization
- on(eventType, handler)
- Attach event handlers to elements as addons
Signals & Reactivity
- S(initialValue)
- Create a signal with an initial value
- S(() => computation)
- Create a derived signal that updates when dependencies change
- S.el(signal, data => element)
- Create reactive elements that update when a signal changes
- S.action(signal, "method", ...args)
- Call custom methods defined on a signal
- signal.get()
- Get the current value of a signal
- signal.set(newValue)
- Update a signal’s value and trigger reactive updates
Component Patterns
- Function Components
- Javascript functions that return DOM elements
- scope Object
- Provides access to component context, signal, host element
- dispatchEvent(type, element)
- Creates a function for dispatching custom events
- Signal Factories
- Functions that create and configure signals with domain-specific behavior
# Best Practices Summary
Code Organization
- Follow the 3PS pattern: Separate state creation, binding to elements, and state updates
- Use component functions: Create reusable UI components as functions
- Create signal factories: Extract reusable signal patterns into factory functions
- Leverage scopes: Use scope for component context and clean resource management
- Event delegation: Prefer component-level event handlers over many individual handlers
When to Use Signals vs. Plain DOM
- Use signals for: Data that changes frequently, multiple elements that need to stay in sync, computed values dependent on other state
- Use plain DOM for: Static content, one-time DOM operations, simple toggling of elements, single-element updates
- Mixed approach: Start with plain DOM and events, then add signals only where needed for reactivity
- Consider derived signals: For complex transformations of data rather than manual updates
- Use event delegation: For handling multiple similar interactions without individual signal bindings
Performance Optimization
- Memoize list items: Use
memo
for items in frequently-updated lists - Avoid unnecessary signal updates: Only update signals when values actually change
- Use AbortSignals: Clean up resources when components are removed
- Prefer derived signals: Use computed values instead of manual updates
- Avoid memoizing fragments: Never memoize DocumentFragments, only individual elements
See the Performance Optimization Guide for detailed strategies.
Common Pitfalls to Avoid
- Excessive DOM Manipulation
- Let signals handle updates instead of manually manipulating the DOM after creation
- Forgetting to Clean Up Resources
- Use scope.signal or AbortSignals to handle resource cleanup when elements are removed
- Circular Signal Dependencies
- Avoid signals that depend on each other in a circular way, which can cause infinite update loops
- Memoizing with Unstable Keys
- Always use stable, unique identifiers as memo keys, not array indices or objects
- Deep Nesting Without Structure
- Break deeply nested element structures into smaller, logical component functions
# Feature Comparison with Other Libraries
Feature | dd<el> | VanJS | Solid | Alpine |
---|---|---|---|---|
No Build Step Required | ✅ | ✅ | ⚠️ JSX needs transpilation | ✅ |
Bundle Size (minified) | ~14kb | ~3kb | ~20kb | ~43kb |
Reactivity Model | Signal-based | Signal-based (basics only) | Signal-based | MVVM + Proxy |
DOM Interface | Direct DOM API | Direct DOM API | Compiled DOM updates | Directive-based |
Server-Side Rendering | ✅ Basic Support | ✅ Basic Support | ✅ Advanced | ❌ |
# Looking Ahead: Future Directions
The dd<el> library continues to evolve, with several areas of focus for future development:
- Future Compatibility: Alignment with the TC39 Signals proposal for native browser support
- SSR Improvements: Enhanced server-side rendering capabilities
- Ecosystem Growth: More utilities, patterns, and integrations with other libraries
- Documentation Expansion: Additional examples, tutorials, and best practices
- TypeScript Enhancements: Improved type definitions and inference
# Contribution and Community
dd<el> is an open-source project that welcomes contributions from the community:
- GitHub Repository: Star, fork, and contribute to the project
- Bug reports and feature requests: Open issues on GitHub
- Documentation improvements: Help expand and clarify these guides
- Examples and case studies: Share your implementations and solutions
Final Thoughts
dd<el> provides a lightweight yet powerful approach to building modern web interfaces with minimal overhead and maximal flexibility. By embracing standard web technologies rather than abstracting them away, it offers a development experience that scales from simple interactive elements to complex applications while remaining close to what makes the web platform powerful.
Whether you’re building a small interactive component or a full-featured application, dd<el>’s combination of declarative syntax, targeted reactivity, and pragmatic design provides the tools you need without the complexity you don’t.
# Tools and Resources
To help you get started with dd<el>, we provide several tools and resources:
- HTML to dd<el> Converter: Easily convert existing HTML markup to dd<el> JavaScript code
- Examples Gallery: Browse real-world examples and code snippets
- Documentation: Comprehensive guides and API reference