CurlyTag - Open Source browser JavaScript template engine.
npm (browser project)
npm install @curlytag/curlytagimport { curlytag } from '@curlytag/curlytag';CDN (browser)
<html>
<head>
<!-- preload the module so it's ready before the script runs -->
<link rel="modulepreload" href="https://cdn.jsdelivr.net/npm/@curlytag/curlytag/curlytag.js">
</head>
<body>
<!-- your content -->
<script type="module">
import { curlytag } from 'https://cdn.jsdelivr.net/npm/@curlytag/curlytag/curlytag.js';
curlytag.parse('Hello, {{ name }}!', { name: 'World' });
</script>
</body>
</html>curlytag.parse('Hello, {{ name }}!', { name: 'World' });
// → Hello, World!render() loads a .html template using the browser's fetch() API:
curlytag.addPath('/views/');
const html = await curlytag.render('home', { title: 'Welcome' });Full documentation: curlytag.com
This project uses Vite+ for formatting (Oxfmt and ESLint Stylistic), linting (Oxlint), browser tests (Vitest and Playwright), and commit hooks.
Open the project in VS Code and select "Reopen in Container". The container will automatically:
- Install Node.js (LTS)
- Install
vpCLI (Vite+) - Install project dependencies
After the container starts, you're ready to work.
-
Install Vite+:
macOS / Linux:
curl -fsSL https://vite.plus | bashWindows:
irm https://vite.plus/ps1 | iex
Alternatively, download and run
vp-setup.exefrom setup.viteplus.dev.
Note
vp-setup.exe is not yet code-signed. Your browser may show a warning when downloading. Click "..." → "Keep" → "Keep anyway" to proceed. If Windows Defender SmartScreen blocks the file when you run it, click "More info" → "Run anyway".
-
Install dependencies:
vp install
-
Install the browsers for the test suite:
vp exec playwright install chromium firefox webkit -
Set up commit hooks:
vp config
vp run check # Format, lint, and validate JavaScript style
vp run fmt # Format with Oxfmt and ESLint Stylistic
vp run lint # Lint with Oxlint
vp test --project browser # Run Chromium, Firefox, and WebKit tests onceTests are organized by feature and should stay split across small files instead of growing a shared catch-all suite.
tests/output/contains plain output and{{ }}variable rendering tests.tests/filters/contains filter tests, with array filters intests/filters/array/.tests/tags/contains tag behavior tests.tests/render.test.jsandtests/add-filter.test.jsstay at the top level because they cover broader integration behavior.
When adding a new filter or tag, prefer creating or extending a focused file in the matching directory rather than restoring cases to a monolithic curlytag.test.js file.
Run the playground in development mode:
vp devVite serves the playground from playground/ using the config in vite.config.ts. Open the local URL printed by the command to work on the editors and examples.
Run tests in watch mode — tests re-run automatically on file changes:
vp test --project browser --watchRun tests with a browser UI for interactive exploration:
vp test --project browser --ui --watchNote
The UI starts at http://localhost:51204/__vitest__/ and stays open as long as the process is running. Always use --watch together with --ui, otherwise the server exits right after the test run.