A simple view system inspired by Blade.
npm install kireThe core engine of Kire, a powerful, expressive, and lightweight template engine for JavaScript/TypeScript environments. Kire is designed to be fast, extensible via plugins, and familiar to developers used to Blade (Laravel) or Edge (AdonisJS).
For the best development experience, syntax highlighting, and autocomplete, install the official VS Code extension:
š Kire Intellisense
- Expressive Syntax: Clean and readable directives like @if, @for, @each, @include, @component.
- Async Support: First-class support for asynchronous operations within templates (e.g., {{ await fetchData() }}).
- Streaming & Defer: Built-in support for streaming responses and out-of-order rendering using @defer.
- Components & Slots: Modern component architecture with slot support and "Wire" capabilities (Livewire-like).
- Extensible: Robust plugin system to add custom directives, elements, and functionality.
- Request Isolation: Use kire.fork() to handle per-request context safely.
- High Performance: Compiles templates to efficient JavaScript functions.
``bash`
npm install kireor
bun add kire
`typescript
import { Kire } from 'kire';
// Initialize Kire
const kire = new Kire({
stream: false, // Enable streaming support (default: false)
silent: false, // Suppress logs (default: false)
});
const template =
;const html = await kire.render(template, {
name: 'World',
isAdmin: true,
users: [{ name: 'Alice' }, { name: 'Bob' }]
});
console.log(html);
`š Key Concepts
$3
By default, all local variables passed to render() are accessible via the it object (e.g., {{ it.title }}). This prevents variable collisions and makes the source of data clear.
You can change this variable name in the options:
`typescript
const kire = new Kire({ varLocals: 'props' }); // Use {{ props.title }}
`$3
Kire supports HTML streaming, allowing you to send the initial page structure immediately and stream heavy content later.
`typescript
const kire = new Kire({ stream: true });// In your template:
// Content inside @defer will be rendered asynchronously and injected later
// using a placeholder and a small script.
const tpl =
;
`$3
When building a web server (like with Hono, Express, or Elysia), you should use kire.fork() for each request. This creates a lightweight copy of the Kire instance that shares the cache but has its own global context (perfect for request-specific data like auth user, request object, etc.).`typescript
app.get('/', (req, res) => {
const requestKire = kire.fork();
requestKire.$global('user', req.user);
return requestKire.render('pages.dashboard');
});
`$3
- Control Flow:
- @if(cond) / @elseif(cond) / @elif(cond) / @else
- @switch(expr) / @case(val) / @default
- Loops:
- @for(item of items) / @empty
- @each(item in items) / @empty (Alias for @for)
- Variables: @const(name = val), @let(name = val)
- Components & Layouts:
- @component('path', props) / @slot('name')
- @layout('path') / @extends('path') (Aliases for @component)
- @section('name') (Alias for @slot)
- @yield('name', default)
- @include('path', locals)
- Stacks: @push('stack'), @stack('stack')
- Blocks: @define('name'), @defined('name')
- Async: @defer (requires streaming)
- HTTP/Forms: @csrf, @method('PUT')`MIT