| name | blecsd-codex-skill |
| description | Best practices and module map for blECSd (TypeScript terminal UI). Use when building, reviewing, or refactoring blECSd apps, widgets, systems, or ECS/game-loop code. |
blECSd Codex Skill
Use this skill to build, review, or refactor blECSd applications and libraries.
Follow Core Principles
- Treat blECSd as a library, not a framework.
- Use functional style only: pure functions, plain data, no classes.
- Use ECS patterns: entities as IDs, components as SoA data, systems as pure transforms.
- Keep input responsive: INPUT phase runs first and drains events.
Choose an API
- Use Game API for games and real-time apps.
- Use ECS API for full control and performance tuning.
Apply the Recommended Workflow
- Pick the API surface.
- Import from
blecsd for typical apps.
- Import from
blecsd/terminal for low-level terminal control.
- Import from
blecsd/components and blecsd/systems for custom pipelines.
- Create the world and screen.
- Call
createWorld and createScreenEntity for ECS API.
- Call
createGame for Game API.
- Build UI with the right abstraction.
- Use widgets for rapid development.
- Use entity factories for composable primitives.
- Use components directly for full control.
- Handle input first.
- Keep input logic in INPUT/EARLY_UPDATE.
- Avoid input processing in RENDER.
- Render after layout.
- Run LAYOUT before RENDER.
- Keep RENDER read-only.
- Optimize only when measured.
- Use frame budget tooling and benchmarks.
- Apply virtualization and dirty tracking for large UIs.
Keep Best Practices in Mind
- Cache queries outside hot loops.
- Keep hierarchies shallow.
- Use
VirtualizedList for lists > 1000 items.
- Mark entities dirty only when state changes.
- Use visibility culling for large scenes.
- Batch updates and render once per frame.
- Store large data outside ECS; keep ECS for UI state.
- Access component arrays directly in tight loops.
Read Deep Dives as Needed
Indexes and summaries for full coverage:
references/DOCS_INDEX.md
references/ROOT_DOCS.md
references/ROOT_DOCS_SUMMARY.md
references/GETTING_STARTED_INDEX.md
references/GETTING_STARTED_SUMMARY.md
references/GUIDES_INDEX.md
references/GUIDES_SUMMARY.md
references/TUTORIALS_INDEX.md
references/TUTORIALS_SUMMARY.md
references/EXAMPLES_INDEX.md
references/EXAMPLES_SUMMARY.md
references/ARCHITECTURE_INDEX.md
references/ARCHITECTURE_SUMMARY.md
references/PERFORMANCE_INDEX.md
references/PERFORMANCE_SUMMARY.md
references/CONTRIBUTING_INDEX.md
references/CONTRIBUTING_SUMMARY.md
references/EXPLORATION_INDEX.md
references/EXPLORATION_SUMMARY.md
API indexes:
references/API_INDEX.md
references/API_CORE.md
references/API_COMPONENTS.md
references/API_WIDGETS.md
references/API_SYSTEMS.md
references/API_TERMINAL.md
references/API_UTILS.md
references/API_3D.md
references/API_DEBUG.md
references/API_INPUT.md
references/API_TEXT.md
Focused deep dives:
references/MODULES.md
references/BEST_PRACTICES.md
references/PERFORMANCE.md
references/SYSTEMS.md
references/LAYOUT.md
references/WIDGETS.md
references/COMPONENTS.md
references/TERMINAL.md
references/TERMINAL_PROTOCOLS.md
references/UTILS.md
references/THREE_D.md
references/ERRORS.md
references/SCHEMAS.md
references/TESTING.md
references/GAME_API.md
references/ECS_API.md
references/ARCHITECTURE.md
Enforce Guardrails
- Never introduce classes or
new (except built-in collections like Map, Set, Error).
- Keep nesting shallow with guard clauses.
- Use Zod validation at system boundaries.
- Prefer ECS systems for behavior; keep state in components.
Use a Quick ECS Example
import {
createWorld,
createScreenEntity,
createBoxEntity,
createGameLoop,
LoopPhase,
inputSystem,
layoutSystem,
renderSystem,
} from 'blecsd';
const world = createWorld();
createScreenEntity(world, { width: 80, height: 24 });
createBoxEntity(world, { x: 2, y: 1, width: 30, height: 10, title: 'Hello' });
const loop = createGameLoop(world, { targetFPS: 60 });
loop.registerSystem(LoopPhase.INPUT, inputSystem);
loop.registerSystem(LoopPhase.LAYOUT, layoutSystem);
loop.registerSystem(LoopPhase.RENDER, renderSystem);
loop.start();