FAQ
Frequently asked questions about unblessed.
General
What is unblessed?
unblessed is a modern, TypeScript-first terminal UI library for building interactive command-line applications. It's built on top of the original blessed library but reimagined for modern development with cross-platform support (Node.js and browsers).
Is unblessed compatible with blessed?
Yes! The @unblessed/blessed package provides 100% backward compatibility with blessed. You can drop it in as a replacement and your existing code should work without changes. See the Migration Guide.
Why choose unblessed over blessed?
- ✅ TypeScript: Full type safety and IDE autocomplete
- ✅ Browser Support: Run terminal UIs in browsers with XTerm.js
- ✅ Modern Build: ESM + CJS, tree-shakeable, actively maintained
- ✅ Better DX: Improved error messages, comprehensive tests, great docs
- ✅ Platform Agnostic: Runtime dependency injection allows portability
Why is it called "unblessed"?
The name reflects that while it's based on blessed, it's been "unblessed" of the legacy patterns and reimagined for modern JavaScript/TypeScript development. It's a fork that has evolved into its own identity.
Installation & Setup
What Node.js version do I need?
unblessed requires Node.js >= 22.0.0. This is due to modern JavaScript features used throughout the codebase.
Which package should I install?
It depends on your use case:
@unblessed/node- For new Node.js projects (recommended)@unblessed/browser- For browser-based terminal UIs@unblessed/blessed- For migrating from blessed@unblessed/core- Only if building custom runtime adapters
Do I need to install types separately?
No! All packages include TypeScript definitions. There's no need for separate @types/* packages.
Can I use unblessed with JavaScript (not TypeScript)?
Absolutely! unblessed works perfectly with plain JavaScript. TypeScript definitions are included for those who want them, but they're completely optional.
Development
Do I need to initialize the runtime?
No! The runtime auto-initializes when you import from @unblessed/node or @unblessed/browser. Just import and use:
import { Screen, Box } from "@unblessed/node";
// Runtime is ready - no setup needed
const screen = new Screen();
Why is my terminal messed up after my app crashes?
When an app crashes, the terminal might stay in alternate buffer mode or have the cursor hidden. Add cleanup handlers:
screen.key(["C-c"], () => {
screen.destroy();
process.exit(0);
});
process.on("uncaughtException", (err) => {
screen.destroy();
console.error(err);
process.exit(1);
});
How do I debug rendering issues?
Enable debug mode:
const screen = new Screen({
debug: true,
log: "./debug.log",
});
This logs all rendering operations to help diagnose issues.
Can I use unblessed with tsx or ts-node?
Yes! unblessed works with all TypeScript runners:
# tsx (recommended)
tsx app.ts
# ts-node
ts-node app.ts
# esbuild
node --loader esbuild-register app.ts
Browser Support
Can I really run terminal UIs in browsers?
Yes! The @unblessed/browser package uses XTerm.js to create a terminal emulator in the browser. Your unblessed widgets render inside it just like in a real terminal.
What doesn't work in browsers?
- Real file system: Virtual FS with bundled data only
- Child processes: Terminal widget won't work
- Native TTY: Always reports as TTY in browsers
See Browser Platform Guide for details.
Do I need Vite to use unblessed in browsers?
No, but Vite is recommended. unblessed works with any modern bundler (Webpack, Rollup, esbuild). See the Browser Guide for bundler configuration.
Widgets & Features
How do I create a widget?
Use the parent option to attach widgets:
const box = new Box({
parent: screen, // Required
content: "Hello",
border: { type: "line" },
});
Why isn't my widget showing?
Common issues:
-
Forgot to call
screen.render():screen.render(); // Must call this! -
Widget is off-screen: Check positioning
// ❌ Bad - might be off screen
box.top = 1000;
// ✅ Good
box.top = "center"; -
No parent: Widget must be attached
// ✅ Always specify parent
const box = new Box({ parent: screen });
How do I handle keyboard input?
Global keys:
screen.key(["C-c", "q"], () => process.exit(0));
Widget-specific keys:
list.key("enter", () => {
const selected = list.selected;
// Handle selection
});
How do I handle mouse events?
Enable mouse on the widget:
const box = new Box({
parent: screen,
mouse: true, // Enable mouse
clickable: true,
});
box.on("click", (data) => {
console.log("Clicked at", data.x, data.y);
});
How do I style widgets?
Use the style object:
const box = new Box({
style: {
fg: "white",
bg: "blue",
border: { fg: "cyan" },
focus: { border: { fg: "green" } },
hover: { bg: "gray" },
},
});
Or use inline tags:
const box = new Box({
content: "{red-fg}Error:{/red-fg} Something went wrong",
tags: true, // Enable tag parsing
});
What colors are supported?
- Named colors:
'red','blue','green', etc. - Hex colors:
'#ff0000','#00ff00' - 256-color:
196(color index) - Default:
'default'or-1
Testing
How do I test terminal UIs?
Use the @unblessed/vrt package for visual regression testing:
import { compareWithGolden } from "@unblessed/vrt";
it("renders correctly", () => {
const screen = new Screen();
const box = new Box({ parent: screen, content: "Test" });
screen.render();
const recording = createRecording(screen);
const result = compareWithGolden("golden.vrt.json", recording);
expect(result.pass).toBe(true);
screen.destroy();
});
See the Testing Guide for details.
Can I use Jest with unblessed?
Yes! unblessed works with Jest, Vitest, and other test frameworks. For Jest, you may need to configure ESM support:
// jest.config.js
export default {
extensionsToTreatAsEsm: [".ts"],
transform: {
"^.+\\.ts$": ["ts-jest", { useESM: true }],
},
};
Performance
Is unblessed fast?
Yes! Performance benchmarks on modern hardware:
- Empty screen render: ~6.5ms
- Complex screen (100 boxes): ~11ms
- Large list (1K items): ~187ms
Use smartCSR: true for optimal performance.
How do I optimize rendering?
-
Enable smart CSR:
const screen = new Screen({ smartCSR: true }); -
Batch updates:
// ❌ Bad - renders 3 times
box1.setContent("One");
screen.render();
box2.setContent("Two");
screen.render();
box3.setContent("Three");
screen.render();
// ✅ Good - renders once
box1.setContent("One");
box2.setContent("Two");
box3.setContent("Three");
screen.render(); -
Use alwaysScroll: false when not needed
See Performance Guide for more tips.
Troubleshooting
My colors aren't showing correctly
Check your terminal's color support:
echo $TERM
# Should be something like "xterm-256color"
Set it if needed:
export TERM=xterm-256color
Mouse events aren't working
- Check terminal support: Not all terminals support mouse
- Enable mouse on widget:
const box = new Box({ mouse: true }); - Check terminal multiplexers: tmux/screen need configuration
Unicode characters aren't rendering
Enable full unicode support:
const screen = new Screen({
fullUnicode: true,
});
Application hangs on exit
Make sure to call screen.destroy():
screen.key(["C-c"], () => {
screen.destroy(); // Important!
process.exit(0);
});
Contributing
How can I contribute?
We welcome contributions! Ways to help:
- 🐛 Report bugs via GitHub Issues
- 💡 Suggest features via GitHub Discussions
- 📖 Improve documentation
- 🧪 Add tests
- ⚡ Submit pull requests
Check the repository for contribution guidelines.
I found a bug, what should I include?
Please include:
- unblessed version (
npm list @unblessed/node) - Node.js version (
node --version) - Terminal emulator and OS
- Minimal code to reproduce
- Expected vs actual behavior
- Screenshots if relevant
Can I use unblessed in commercial projects?
Yes! unblessed is MIT licensed - use it freely in commercial and open-source projects.
Project Status
Is unblessed production-ready?
unblessed is currently in alpha. The API is stable and backward-compatible with blessed, but:
- ✅ Core functionality is solid (2,112 tests passing)
- ✅ Safe for non-critical applications
- ⚠️ API may have minor changes before 1.0
- ⚠️ Some edge cases may not be covered
We welcome alpha testers to help us reach 1.0!
What's the roadmap?
Current priorities:
- Alpha: API stabilization, bug fixes, documentation
- Beta: Performance optimization, more examples
- 1.0: Production-ready release
See GitHub Milestones for details.
How often is unblessed updated?
We follow semantic versioning with automated releases:
- Patch releases (bug fixes): As needed
- Minor releases (features): Monthly
- Major releases (breaking changes): Rare, planned ahead
Getting Help
Where can I get help?
- 📖 Documentation: Start here - most questions are answered in the docs
- 💬 GitHub Discussions: Ask questions, share ideas
- 🐛 GitHub Issues: Report bugs, request features
- 📧 Direct Contact: For security issues only
The docs don't answer my question
We're always improving! Please:
- Ask in GitHub Discussions
- Suggest doc improvements via issues
- Submit a PR to improve documentation
Still Have Questions?
If your question isn't answered here:
- Browse the Documentation - Comprehensive guides
- Ask on GitHub Discussions - Community help
- Check the API Reference - Detailed API docs
- Report an Issue - Found a bug?