A Blade-like template engine plugin for Bun, enabling simple and powerful templating with .stx files.
- 🦋 Laravel Blade-like syntax
- 🚀 Fast and lightweight
- 📦 Zero config
bun add bun-plugin-stx
Add the plugin to your bunfig.toml
:
preload = [ "bun-plugin-stx" ]
# or as a serve plugin
[serve.static]
plugins = [ "bun-plugin-stx" ]
Or register the plugin in your build script:
import { build } from 'bun'
import stxPlugin from 'bun-plugin-stx'
await build({
entrypoints: ['./src/index.ts', './templates/home.stx'],
outdir: './dist',
plugins: [stxPlugin],
})
In your build script or Bun configuration:
// build.js
import { build } from 'bun'
import stxPlugin from 'bun-plugin-stx'
await build({
entrypoints: ['./src/index.ts', './templates/home.stx'],
outdir: './dist',
plugins: [stxPlugin],
})
You can import .stx files directly in your ESM code:
// app.js
import homeTemplate from './templates/home.stx'
// Use the processed HTML content
document.body.innerHTML = homeTemplate
You can serve .stx files directly with Bun's server:
// server.js
import { serve } from 'bun'
import homeTemplate from './home.stx'
serve({
port: 3000,
fetch(req) {
return new Response(homeTemplate, {
headers: { 'Content-Type': 'text/html' }
})
}
})
Or use as route handlers:
import about from './about.stx'
// server.js
import home from './home.stx'
export default {
port: 3000,
routes: {
'/': home,
'/about': about
}
}
STX templates use a syntax inspired by Laravel Blade. Templates can contain HTML with special directives for rendering dynamic content.
<!DOCTYPE html>
<html>
<head>
<title>STX Example</title>
<script>
// Define your data as an ESM export
export const title = "Hello World";
export const items = ["Apple", "Banana", "Cherry"];
export const showFooter = true;
</script>
</head>
<body>
<h1>{{ title }}</h1>
<ul>
@foreach (items as item)
<li>{{ item }}</li>
@endforeach
</ul>
@if (showFooter)
<footer>Copyright 2023</footer>
@endif
</body>
</html>
There are two ways to expose data in your STX templates:
<script>
// Modern ESM named exports
export const title = "Hello World";
export const count = 42;
// Export functions
export function getFullName(first, last) {
return `${first} ${last}`;
}
// Export default object
export default {
items: ["Apple", "Banana", "Cherry"],
showDetails: true
};
</script>
<script>
// Legacy CommonJS exports
module.exports = {
title: "Hello World",
items: ["Apple", "Banana", "Cherry"],
showFooter: true
};
</script>
Display content with double curly braces:
<h1>{{ title }}</h1>
<p>{{ user.name }}</p>
Use @if
, @elseif
, and @else
for conditional rendering:
@if (user.isAdmin)
<div class="admin-panel">Admin content</div>
@elseif (user.isEditor)
<div class="editor-tools">Editor tools</div>
@else
<div class="user-view">Regular user view</div>
@endif
Iterate over arrays with @foreach
:
<ul>
@foreach (items as item)
<li>{{ item }}</li>
@endforeach
</ul>
Use @for
for numeric loops:
<ol>
@for (let i = 1; i <= 5; i++)
<li>Item {{ i }}</li>
@endfor
</ol>
Output unescaped HTML content:
{!! rawHtmlContent !!}
STX includes TypeScript declarations for importing .stx files. Make sure your tsconfig.json
includes the necessary configuration:
{
"compilerOptions": {
// ... your other options
"types": ["bun"]
},
"files": ["src/stx.d.ts"],
"include": ["**/*.ts", "**/*.d.ts", "*.stx", "./**/*.stx"]
}
Create a declaration file (src/stx.d.ts
):
// Allow importing .stx files
declare module '*.stx';
Run a development server with your STX templates:
// serve.ts
import home from './home.stx'
const server = Bun.serve({
routes: {
'/': home,
},
development: true,
fetch(req) {
return new Response('Not Found', { status: 404 })
},
})
console.log(`Listening on ${server.url}`)
To test the plugin with the included examples:
- Build the test file:
bun run test-build.ts
- Run the test server:
bun run serve-test.ts
- Open your browser to the displayed URL (typically
http://localhost:3000
).
The plugin works by:
- Extracting script tags from .stx files
- Creating an execution context with variables from the script
- Processing Blade-like directives (@if, @foreach, etc.) into HTML
- Processing variable tags ({{ var }}) with their values
- Returning the processed HTML content
bun test
Please see our releases page for more information on what has changed recently.
Please review the Contributing Guide for details.
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
For casual chit-chat with others using this package:
Join the Stacks Discord Server
You will always be free to use any of the Stacks OSS software. We would also love to see which parts of the world Stacks ends up in. Receiving postcards makes us happy—and we will publish them on our website.
Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
Many thanks to the following core technologies & people who have contributed to this package:
The MIT License (MIT). Please see LICENSE for more information.
Made with 💙