Building a Terminal Coffee Shop with charsm in JavaScript.
A practical example to TUI's in Javascript
This article picks up where we left off in the introduction to charsm
and huh
forms. If you haven’t read it yet, feel free to check it out first for a solid foundation.
Today, we’re taking a more practical approach—building a "real" example. Ready to dive in? Let’s get started.
Setting Up Your Project
First things first, set up a new JavaScript project and install charsm
:
pnpm add charsm
Note: To use shared libraries in JavaScript, you’ll need Node.js with native modules support and
node-gyp
for the C bindings.
If you haven’t already, reinstall Node.js and enable the native modules option during setup.
Introducing the Coffee && Kernels Shop
A cozy coffee shop with premium blends, customizations, and delightful extras.
Like any serious application, we need to start with a loader screen—because we’re doing real work over here. 🔧
Adding a Loader Screen
Here’s how we set up the loader with charsm
:
import { huh, initLip, Lipgloss } from "charsm";
huh.SetTheme("Catppuccin");
huh.Spinner(5, "doing real work behind the scenes🔩");
Now that we’re warmed up, let’s add a catchphrase to welcome customers.
Crafting the Perfect Catchphrase
;(async function () {
const ini = await initLip();
if (!ini) {
console.log("Failed to initialize charsm");
return;
}
const lip = new Lipgloss();
lip.createStyle({
id: "primary",
canvasColor: { color: "#faf3dd" },
padding: [1],
margin: [1],
bold: true,
});
const styledText = lip.apply({
value: "A cozy coffee shop with premium blends, customizations, and delightful extras.",
});
console.log(styledText);
})();
Looking good so far! Next, let’s dive into what makes a coffee shop: coffee.
The Actual Coffee
We’ll define all the components up front, but feel free to inline them if that’s your style:
const coffee = huh.Select(
"Select your favorite brew to kickstart your day.",
["Espresso", "Latte", "Cappuccino", "Americano", "Mocha", "Flat White"]
);
const coffeeMilk = huh.Select("Milk or Alternatives", [
"Whole Milk",
"Skim Milk",
"Soy Milk",
"Oat Milk",
"No Milk",
]);
const coffeeSweetener = huh.Select("Sweetener", [
"None",
"Sugar",
"Honey",
"Stevia",
]);
;(async function () {})();
Extras and Snacks
What’s coffee without extras and snacks? Pairing products is how we drive up sales! 😎
const extras = huh.Select("Add something special to your coffee.", [
"Whipped Cream",
"Cinnamon Sprinkle",
"Chocolate Shavings",
"Extra Shot of Espresso",
]);
const snack = huh.Select(
"Would you like a snack to pair with your coffee?",
["Croissant", "Muffin", "Banana Bread", "Granola Bar", "None"]
);
Final Details: The Call to Action
Let’s add a personal touch and encourage customers to join our loyalty program:
const name = new huh.NewInput(
{
Title: "What's your name?",
Description: "So we can call you when your order is ready.",
Placeholder: "e.g., John Doe",
validators: "required",
},
0
);
name.load();
const callToAct = huh.Confirm(
"Would you like to join our loyalty program?",
"Sign Me Up",
"No Thanks."
);
Bringing It All Together
Finally, let’s group everything into a form:
;(async function () {
console.log(styledText);
const cgroup = huh.CreateGroup(`${coffee.id},${coffeeMilk.id},${coffeeSweetener.id}`);
const egroup = huh.CreateGroup(`${extras.id},${snack.id}`);
const actiongroup = huh.CreateGroup(`${name.id},${callToAct.id}`);
huh.CreateForm(`${cgroup},${egroup},${actiongroup}`);
// Process form input
console.log(coffee.value, coffeeMilk.value, coffeeSweetener.value);
console.log(extras.value, snack.value);
console.log(name.value, callToAct.value);
})();
What’s Next?
Of course, this is just a pseudo shop. We could make it even nicer—maybe add ASCII logos or implement working payments. You know what? That’s an idea for another article! 🎉
This tutorial was just a fun, practical dive into composing TUI components to create something useful. The charsm
library is evolving, and I’ll be adding more features soon.
In the meantime, feel free to check out (and star! ⭐) the project repo. Follow me here for more hands-on tutorials in backend, systems, and desktop engineering. Stay tuned!
Would love to see a repo with the example code, feels a bit like I have to piece everything together myself.