Best Practices
What Tkeron Does
Build time:
- Runs
.pre.ts— full DOM access, TypeScript, Bun APIs - Executes
.com.ts— reads attributes, generates HTML - Inlines
.com.html— static replacement - Converts
.com.md— Markdown to HTML - Compiles TypeScript to JavaScript
- Copies assets
Runtime (browser):
- Your compiled JavaScript runs
- Zero framework overhead
- Use any browser APIs
Component Design
HTML Components — static, reusable markup
<!-- nav-menu.com.html -->
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
Use for: Headers, footers, layout elements, static UI patterns.
TypeScript Components — dynamic generation
// user-badge.com.ts
const name = com.getAttribute("name") || "Guest";
com.innerHTML = `<span class="badge">${name}</span>`;
Use for: Dynamic lists, conditional rendering, computed HTML.
Markdown Components — content sections
<!-- about-section.com.md -->
## About Us
We build **great tools** for developers.
Use for: Content-heavy sections, docs, FAQs, blog content.
Pre-rendering — document-wide manipulation
// index.pre.ts
const res = await fetch("https://api.example.com/data");
const data = await res.json();
document.getElementById("content").textContent = data.title;
Use for: API data fetching, SEO meta tags, build metadata.
File Organization
websrc/
├── index.html
├── index.ts
├── index.pre.ts
├── components/
│ ├── ui/
│ │ ├── my-button.com.html
│ │ └── my-card.com.html
│ ├── layout/
│ │ ├── site-header.com.html
│ │ └── site-footer.com.html
│ └── content/
│ └── about-section.com.md
├── utils/
│ └── api.ts
└── pages/
├── about/
│ └── about.html
└── contact/
└── contact.html
Naming
Components: user-card.com.html, nav-menu.com.ts (kebab-case, must have hyphen)
Files: index.html, api-service.ts (lowercase, hyphens)
Build vs Runtime
| Build time (.pre.ts, .com.ts) | Runtime (browser) | |
|---|---|---|
| Environment | Bun | Browser |
| APIs | fetch(), Bun.file(), Node APIs | window, localStorage, DOM |
| npm packages | ✅ Available | ❌ Not bundled |
| Event listeners | ❌ Not preserved | ✅ Works normally |
Browser Interactivity
Components run at build time. For runtime interactivity:
// index.ts - runs in browser
document.getElementById("btn")?.addEventListener("click", () => {
console.log("clicked");
});
NPM Packages
Tkeron does NOT bundle npm packages for browser.
Build time — works:
// .pre.ts
import _ from "lodash";
Browser — use alternatives:
- CDN:
<script src="https://cdn.jsdelivr.net/npm/lodash"></script> - External bundler (Vite, esbuild)
- Write vanilla JavaScript
Error Handling
Always handle errors and timeouts in .pre.ts and .com.ts:
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch(url, { signal: controller.signal });
return await res.json();
} catch {
return fallbackData;
}
XSS Prevention
Always escape dynamic content:
const escapeHtml = (str: string): string =>
str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
const text = com.getAttribute("text") || "";
com.innerHTML = `<p>${escapeHtml(text)}</p>`;
Performance
- Cache external data when possible
- Use
Promise.all()for parallel API calls - Keep component output small — it gets duplicated per usage
- Use CSS classes, not inline styles
Development Workflow
tk dev # Start dev server (hot reload)
# Edit files, browser auto-reloads
tk build # Build for production
tk dev 8080 # Dev on custom port
Next Steps
- Overview — Return to docs home
- CLI Reference — All commands
- Common Issues — Troubleshooting