TargetJS: Code-Ordered Reactivity and Targets - A New Paradigm for UI Development
Introduction Reactive methods, where one method runs automatically when another completes, whether synchronous or asynchronous, represent a powerful idea in modern development. TargetJS introduces a distinctly innovative approach to this concept: it enables methods to react exclusively to their immediately preceding counterparts, fostering a declarative and intuitive code flow. TargetJS also brings in a second key concept: it unifies both variables and methods into a new construct called “Targets”. Targets also provide state, loops, timing, and more, whether it's a variable or a function. When these two ideas are combined: code-ordered reactivity and Targets, they unlock a fundamentally new way of coding that simplifies everything from animations and UI updates to API calls and state management. The result is code that is not only more intuitive to write but also significantly more compact. Understanding TargetJS Syntax: Reactive Postfixes TargetJS uses the postfixes $ and $$ appended to target names for defining reactive behaviors. While initially appearing a bit cryptic, this convention provides a highly compact and declarative way to control execution flow. $ Postfix (Immediate Reactivity): A target name ending with a single $ (e.g., height$) indicates that this target will execute every time its immediately preceding target runs or emits a new value. If the preceding target involves an asynchronous operation like an API call, the reactive target activates when the response is received. If there are multiple API calls made, $ postfix ensures that the target reacts to the first API result when it becomes available, then the second, and so on, maintaining a strict, code-ordered sequence of operations. $$ Postfix (Full Completion Reactivity): A target name ending with a double $$ (e.g., fetch$$) signifies a powerful reactive trigger. This target will activate only after its immediately preceding targets have fully and comprehensively completed all of their operations. This includes: The successful resolution of any timed sequences, such as animations. The completion and return of results from all associated API calls. The finalization of all tasks, animations, and API calls initiated by any dependent child targets that were themselves triggered by a preceding target. This ensures a robust and reliable execution order, guaranteeing that the $$ target runs only when its predecessors' entire job is truly done. Targets: The Building Blocks of TargetJS Targets provide a unified interface for both variables and methods. Each Target comes equipped with a built-in set of capabilities: State Management: Targets are inherently stateful, enabling implicit state handling across your application. Iterations: They can iterate towards defined values, making them perfect for creating smooth animations. Conditional Execution: Targets can be configured to execute only when specific conditions are met. Execution timing: Targets enable fine-grained control over when they execute. Code-Ordered Execution: Targets execute sequentially and predictably in the order they are written within a JavaScript object, thanks to ES2015's guaranteed property order. An All-in-One Solution The elegance of TargetJS emerges when its two innovations: Reactivity and Targets, work in concert. The combination allows TargetJS to serve as a consistent, all-in-one solution for most front-end development needs, eliminating the typical fragmentation of tools and libraries. Declarative UI Rendering: Define your user interface using Targets, and let TargetJS automatically manage rendering updates. Animations: Leverage a target's built-in iteration, looping, and timing capabilities alongside reactivity to create complex animations with minimal effort. API Integration: Execute API calls as targets and utilize their reactivity features to automatically process responses. State Management: With targets inherently managing their own state, application state management becomes implicit. Event Handling: Attach event listeners directly as targets to work consistently with the rest of the application Examples in Action To demostrate the power and simplicity of TargetJS, let's explore its concepts through practical examples. We'll begin with a simple animation and incrementally expand it to demonstrate API integration, event handling, and dynamic UI updates. Growing and Shrinking Box: Declarative Animation The example below creates a element with dynamic width and height. background, width, and height targets are automatically mapped to the element’s styles. If no element type is specified, a is used by default. import { App } from 'targetj'; App({ background: 'mediumpurple', width: [{ list: [100, 250, 100] }, 50, 10], // width animates through 100 → 250 → 100, over 50 steps with 10ms intervals. height$() { // `$` creates a reactive target: the `height` updates each

Introduction
Reactive methods, where one method runs automatically when another completes, whether synchronous or asynchronous, represent a powerful idea in modern development. TargetJS introduces a distinctly innovative approach to this concept: it enables methods to react exclusively to their immediately preceding counterparts, fostering a declarative and intuitive code flow.
TargetJS also brings in a second key concept: it unifies both variables and methods into a new construct called “Targets”. Targets also provide state, loops, timing, and more, whether it's a variable or a function.
When these two ideas are combined: code-ordered reactivity and Targets, they unlock a fundamentally new way of coding that simplifies everything from animations and UI updates to API calls and state management. The result is code that is not only more intuitive to write but also significantly more compact.
Understanding TargetJS Syntax: Reactive Postfixes
TargetJS uses the postfixes $
and $$
appended to target names for defining reactive behaviors. While initially appearing a bit cryptic, this convention provides a highly compact and declarative way to control execution flow.
$ Postfix (Immediate Reactivity):
A target name ending with a single $
(e.g., height$
) indicates that this target will execute every time its immediately preceding target runs or emits a new value. If the preceding target involves an asynchronous operation like an API call, the reactive target activates when the response is received. If there are multiple API calls made, $
postfix ensures that the target reacts to the first API result when it becomes available, then the second, and so on, maintaining a strict, code-ordered sequence of operations.
$$
Postfix (Full Completion Reactivity):
A target name ending with a double $$
(e.g., fetch$$
) signifies a powerful reactive trigger. This target will activate only after its immediately preceding targets have fully and comprehensively completed all of their operations. This includes:
- The successful resolution of any timed sequences, such as animations.
- The completion and return of results from all associated API calls.
- The finalization of all tasks, animations, and API calls initiated by any dependent child targets that were themselves triggered by a preceding target.
This ensures a robust and reliable execution order, guaranteeing that the $$
target runs only when its predecessors' entire job is truly done.
Targets: The Building Blocks of TargetJS
Targets provide a unified interface for both variables and methods. Each Target comes equipped with a built-in set of capabilities:
- State Management: Targets are inherently stateful, enabling implicit state handling across your application.
- Iterations: They can iterate towards defined values, making them perfect for creating smooth animations.
- Conditional Execution: Targets can be configured to execute only when specific conditions are met.
- Execution timing: Targets enable fine-grained control over when they execute.
- Code-Ordered Execution: Targets execute sequentially and predictably in the order they are written within a JavaScript object, thanks to ES2015's guaranteed property order.
An All-in-One Solution
The elegance of TargetJS emerges when its two innovations: Reactivity and Targets, work in concert. The combination allows TargetJS to serve as a consistent, all-in-one solution for most front-end development needs, eliminating the typical fragmentation of tools and libraries.
- Declarative UI Rendering: Define your user interface using Targets, and let TargetJS automatically manage rendering updates.
- Animations: Leverage a target's built-in iteration, looping, and timing capabilities alongside reactivity to create complex animations with minimal effort.
- API Integration: Execute API calls as targets and utilize their reactivity features to automatically process responses.
- State Management: With targets inherently managing their own state, application state management becomes implicit.
- Event Handling: Attach event listeners directly as targets to work consistently with the rest of the application
Examples in Action
To demostrate the power and simplicity of TargetJS, let's explore its concepts through practical examples. We'll begin with a simple animation and incrementally expand it to demonstrate API integration, event handling, and dynamic UI updates.
Growing and Shrinking Box: Declarative Animation
The example below creates a Explanation
Targets execute precisely in the order they are defined:
The example above can also be implemented directly in HTML, utilizing tg- attributes that mirror the object literal keys used in JavaScript: Let's extend our previous example to demonstrate how TargetJS handles asynchronous operations. We'll fetch user details from an API, but we also want this API call to initiate only after the box animation has fully completed. Explanation
This example introduces two new targets:
Together, these targets orchestrate the flow: animation completes, then the API call happens, then the UI updates with the fetched data, all managed declaratively and in code order.
Let's expand our box further by adding a click handler. The goal is to change the box's background color to orange when clicked, pause for two seconds, and then revert the background back to its original mediumpurple. This demonstrates how event handling integrates consistently with TargetJS's reactive and timing mechanisms. Explanation:
This example layers event handling and sequential actions onto our existing box:
This sequence demonstrates how TargetJS allows you to define complex, timed flow and responding to user input and guaranteeing execution order.
To showcase TargetJS's ability to handle creating dynamic collections of elements, let's create ten boxes instead of just one. Each box will be added with a slight delay, undergo its own animation, fetch its own user details, and include the click handler from the previous example. Once all these individual box processes (creation, animation, API calls) are complete, we'll trigger a final, collective action: changing all their backgrounds to green. Explanation:
This advanced example demonstrates TargetJS's capability to manage complex, dynamic UI scenarios:
Only when every sub-task initiated by children is finished will What if If This example highlights TargetJS's ability to orchestrate complex, dependent operations across multiple elements in a compact, declarative, and code-ordered fashion.
Ready to learn more?
background
, width
, and height
targets are automatically mapped to the element’s styles. If no element type is specified, a
import { App } from 'targetj';
App({
background: 'mediumpurple',
width: [{ list: [100, 250, 100] }, 50, 10], // width animates through 100 → 250 → 100, over 50 steps with 10ms intervals.
height$() { // `$` creates a reactive target: the `height` updates each time `width` executes
return this.prevTargetValue / 2;
}
});
background
: This target runs first, setting the element's background color to mediumpurple
. Once the assignment is complete, its lifecycle ends.width
: Next, the width
target takes over. It's configured to animate through a list of values (100, 250, 100), performing 50 steps with a 10ms pause between each step, creating a grow-then-shrink effect.height$
: Finally, the height$
target demonstrates TargetJS's reactivity. Because its name ends with a single $
postfix, height$
is explicitly declared to react whenever its immediately preceding target (width) executes. As width
animates and changes its value, height$
automatically re-runs, setting its value to half of width's value. This creates a synchronized and responsive height.
Adding an API Call
import { App } from 'targetj';
App({
background: 'mediumpurple',
width: [{ list: [100, 250, 100] }, 50, 10],
height$() {
return this.prevTargetValue / 2;
},
fetch$$: 'https://targetjs.io/api/randomUser?id=user0', // `$$` ensures this runs ONLY after all preceding tasks (like 'width' animation) are fully complete
html$() { // `$` makes this reactive: it runs each time `fetch$$` resolves with data
return this.prevTargetValue.name; // 'prevTargetValue' holds the resolved API response
}
});
fetch$$
: fetch
target is a specialized target designed to retrieve data when given a URL string. Since its name ends with a $$
postfix, as previously discussed, this indicates that fetch$$
will activate only after preceding targets fully completed all of its operations. This guarantees the API call is initiated at the precise moment the animation finishes.html$
: Following fetch$$
, the html
target is responsible for setting the text content of the div
element to the fetched user's name. The $
postfix here signifies that html$
is a reactive target that executes each time its immediately preceding target (fetch$$
) provides a result. In this context, this.prevTargetValue
will hold the successfully resolved data from the API call, allowing html$
to dynamically display the user's name as soon as it's available.
Attaching a Click Handler
import { App } from 'targetj';
App({
background: 'mediumpurple',
width: [{ list: [100, 250, 100] }, 50, 10],
height$() {
return this.prevTargetValue / 2;
},
fetch$$: 'https://targetjs.io/api/randomUser?id=user0',
html$() {
return this.prevTargetValue.name;
},
onClick() { // Special target that runs when the element is clicked
this.setTarget('background', 'orange', 30, 10); // Animates background to orange over 30 steps
},
pause$$: { interval: 2000 }, // `$$` ensures this runs ONLY after the preceding 'onClick' animation is fully complete
purpleAgain$$() { // `$$` ensures this runs ONLY after `pause$$` completes (2-second interval)
this.setTarget('background', 'mediumpurple', 30, 10); // Animates background back to mediumpurple
}
});
onClick
: This is a special TargetJS function that automatically runs whenever the associated element is clicked. Inside, this.setTarget('background', 'orange', 30, 10)
imperatively triggers a new animation, changing the background color to orange over 30 steps.pause$$
: Notice the $$
postfix. This pause$$
target is configured with an interval of 2000 milliseconds (2 seconds). Crucially, its $$
postfix means it will only begin its 2-second pause after its immediately preceding target (onClick) has fully completed its animation of changing the background to orange.purpleAgain$$
: Also ending with $$
, this target executes only after the pause$$
target has finished its 2-second execution. It then uses this.setTarget again to animate the background color back to mediumpurple
.
Let's Make it More Complicated :)
import { App } from 'targetj';
App({
children: { // Special target for create a collection of child objects
cycles: 9, // Creates 10 children (from cycle 0 to 9)
interval: 100, // Adds a new child every 100 milliseconds
value(cycle) {
return {
background: 'mediumpurple',
width: [{ list: [100, 250, 100] }, 50, 10],
height$() { return this.prevTargetValue / 2; },
fetch$$: `https://targetjs.io/api/randomUser?id=user${cycle}`, // Each child fetches a unique user
html$() { return this.prevTargetValue.name; },
onClick() { this.setTarget('background', 'orange', 30, 10); },
pause$$: { interval: 2000 },
purpleAgain$$() { this.setTarget('background', 'mediumpurple', 30, 10); }
};
}
},
greenify$$() { // `$$` ensures this runs ONLY after ALL children have completed ALL their tasks
this.getChildren().forEach(child => child.setTarget("background", "green", 30, 10)); // Iterates and animates each child's background
}
});
children
: A special target construct used to create a collection of child objects. Each time it executes, the returned object or objects are added to the current object. The cycles
property specifies that the value function will run 10 times (from cycle
0 to 9), thus creating 10 individual box elements.
The interval
property ensures that each new box is created and added to the UI every 100 milliseconds.
The value(cycle)
function return the same object element from the previous example.greenify$$
: This target demonstrates the $$
postfix's full completion reactivity at a higher level. The greenify$$
target will execute only after the entire children target has comprehensively completed all of its work. This includes:
fetch
) for each child.html
) for each child.greenify$$
runs. It then uses this.getChildren().forEach(child => child.setTarget("background", "green", 30, 10))
to iterate over all the created child boxes and animate their backgrounds to green.
greenify
ends with only one $
?
greenify
ended with only one $
(i.e., greenify$
), it would exhibit immediate reactivity to its preceding target children
. Instead of waiting for all 10 children to be fully animated, etc, greenify$
would run immediately each time a new child is added.