TypeScript Components
TypeScript components (.com.ts files) let you create dynamic, logic-driven components that run at build time. They have access to attributes and can generate HTML programmatically.
Quick Start
Create a .com.ts file:
// user-greeting.com.ts
const name = com.getAttribute("name") || "World";
com.innerHTML = `<h1>Hello, ${name}!</h1>`;
Use it with attributes:
<user-greeting name="Alice"></user-greeting>
<user-greeting name="Bob"></user-greeting>
<user-greeting></user-greeting>
Build output:
<h1>Hello, Alice!</h1>
<h1>Hello, Bob!</h1>
<h1>Hello, World!</h1>
How They Work
The com Variable
Every .com.ts file has access to a special com variable:
com.getAttribute("attr-name"); // Read attributes
com.innerHTML = "..."; // Set content (this is what's kept)
com.tagName; // Get element name
Only the innerHTML you set is included in the final output.
Build-Time Execution
.com.ts files run during the build process with Bun runtime, not in the browser:
Build Time:
1. Find <user-card name="John">
2. Execute user-card.com.ts
3. Capture com.innerHTML
4. Replace <user-card> with the innerHTML
Component Naming
Same rules as HTML components:
- End with
.com.ts - Use lowercase with hyphens
- Must contain at least one hyphen
Component Resolution
Tkeron looks for .com.ts files in this order:
- Same directory as the file using it
- Any subdirectory of
websrc/via glob search
You can organize components in subdirectories and they'll be found automatically.
IDE Support
Tkeron projects include tkeron.d.ts for IntelliSense:
declare const com: HTMLElement;
This enables autocomplete for com.getAttribute(), com.innerHTML, etc.
Examples
Attribute-Based Content
// user-badge.com.ts
const name = com.getAttribute("name") || "Guest";
const role = com.getAttribute("role") || "User";
com.innerHTML = `
<div class="badge">
<span class="badge-name">${name}</span>
<span class="badge-role">${role}</span>
</div>
`;
Dynamic Lists
// item-list.com.ts
const count = parseInt(com.getAttribute("count") || "3");
const items = [];
for (let i = 1; i <= count; i++) {
items.push(`<li>Item ${i}</li>`);
}
com.innerHTML = `<ul class="item-list">${items.join("")}</ul>`;
Conditional Rendering
// alert-box.com.ts
const type = com.getAttribute("type") || "info";
const message = com.getAttribute("message") || "";
const colors: Record<string, string> = {
info: "#3b82f6",
success: "#22c55e",
warning: "#f59e0b",
error: "#ef4444",
};
const color = colors[type] || colors.info;
com.innerHTML = `
<div style="padding: 1rem; background: ${color}20; border-left: 4px solid ${color};">
<strong>${type.toUpperCase()}</strong>
<p>${message}</p>
</div>
`;
Importing Modules
// product-card.com.ts
import { formatPrice } from "./utils";
const name = com.getAttribute("name") || "Product";
const price = parseFloat(com.getAttribute("price") || "0");
com.innerHTML = `
<div class="product-card">
<h3>${name}</h3>
<p class="price">${formatPrice(price)}</p>
</div>
`;
Using External APIs
// weather-widget.com.ts
const city = com.getAttribute("city") || "London";
const response = await fetch(`https://api.example.com/weather?city=${city}`);
const weather = await response.json();
com.innerHTML = `
<div class="weather-widget">
<h3>${city}</h3>
<div>${weather.temperature}°C — ${weather.condition}</div>
</div>
`;
Note: The API call happens once at build time. The output is static HTML.
Limitations
- No event listeners — Lost in static output. Use regular
.tsfiles for interactivity - No DOM access beyond
com— Use pre-rendering for document-wide access - No reactive state — Components run once at build time
- No runtime data — Can't access
localStorage,window, etc.
Best Practices
✅ Validate attributes — Check types and allowed values ✅ Escape HTML — Prevent XSS with attribute content ✅ Use TypeScript types — Leverage full TS support ✅ Extract complex logic — Import from utility modules
❌ Don't use for simple static content — Use HTML Components instead
Next Steps
- HTML Components — Simpler static components
- Markdown Components — Content in Markdown
- Pre-rendering — Document-wide transformations
- CLI Reference — Build options