Welcome to the fourth chapter! In the previous chapter, Component Integration Adapter, we built a "plug" that connects our Settings component to the system. We ended with a function that returns a React element: <Settings />.
But here is a puzzle: Terminals understand text, not React components.
If you try to console.log(<Settings />), you will just see a confusing object full of data. You won't see an interactive user interface.
In this chapter, we will learn about the Local JSX Execution Strategy. This is the specific "engine" that knows how to take that React element, render it as a visual interface in your terminal, and handle the user's interaction.
Imagine walking down a busy street (the Command Line). Usually, you just walk past buildings (background tasks).
But sometimes, you see a Pop-Up Store.
In our project:
The Local JSX Execution Strategy is the construction crew that builds the store, waits for you to leave, and then takes it down.
How does the system know to build a Pop-Up Store instead of just running a background script?
We told it to do so back in Chapter 1, inside our index.ts.
// index.ts
const config = {
name: 'config',
// THIS LINE defines the strategy:
type: 'local-jsx',
load: () => import('./config.js'),
} satisfies Command
By setting type: 'local-jsx', you triggered a specific chain of events in the system's core.
LocalJSXCommandCall
In the previous chapter, we used a type called LocalJSXCommandCall. This type enforces a specific contract (or agreement) between your code and the system.
The Agreement:
onDone callback.onDone when the user wants to leave.
Let's look at how this strategy handles the inputs and outputs to make the config command work.
When the strategy starts, it takes the React element returned by your adapter and uses a library (like ink) to draw it using text characters.
// Your adapter (config.tsx) returns this:
<Settings onClose={onDone} ... />
System Output: Instead of raw data, the user sees:
โโโ Config Panel โโโโโโโโโ
โ [x] Dark Mode โ
โ [ ] Notifications โ
โ โ
โ [ Save ] [ Cancel ] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโ
This is the most important part of the strategy. Unlike a normal script that runs from top to bottom and exits immediately, a Local JSX command pauses.
It keeps the application running so the user can use the arrow keys to select "Dark Mode" or press Enter on "Save".
The system will wait forever unless we tell it to stop. This is why passing the onDone function was critical in Chapter 3.
// Inside your Component (simplified):
<Button onPress={() => {
// 1. User clicks button
// 2. Component calls prop
props.onClose();
}}>
Close
</Button>
When props.onClose() runs, it triggers the system's onDone, which tells the strategy: "The user has left the Pop-Up Store. Tear it down."
Let's visualize the lifecycle of this strategy using a diagram.
The code inside the system that manages this is complex, but we can look at a simplified version to understand the logic. It uses a JavaScript Promise to handle the waiting.
// core/strategies/local-jsx.ts (Simplified)
import { render } from 'ink'; // The library that draws React in terminal
export async function executeLocalJSX(commandFn, context) {
// 1. Create a Promise that waits for a signal
return new Promise((resolve) => {
// 2. Define the signal function
const onDone = () => {
resolve(); // This unlocks the Promise
};
// 3. Get your component, passing the signal
const uiComponent = commandFn(onDone, context);
// 4. Render it to the screen
const { unmount } = render(uiComponent);
// The code STOPS here until 'resolve()' is called above
}).then(() => {
// 5. Cleanup after resolve() happens
console.log("Exiting...");
});
}
Breakdown:
new Promise: This tells JavaScript, "Don't finish this function yet. Wait until resolve is called."render(uiComponent): This paints your UI to the terminal.onDone -> resolve: When your component calls onDone, it triggers resolve..then(...): The promise completes, the function finishes, and the command exits.Without the Local JSX Execution Strategy, your command would either:
This strategy abstracts away all the complexity of managing terminal raw mode, input streams, and rendering loops. It lets you focus purely on writing standard React code in your Settings component.
In this chapter, we explored the Local JSX Execution Strategy.
type: 'local-jsx' tells the system to treat the command as an interactive UI.onDone is the key that unlocks that Promise and allows the application to exit cleanly.
You have now completed the journey for the config command!
You are now ready to build your own interactive CLI commands!
Generated by Code IQ