{"id":22490006,"url":"https://github.com/alexewerlof/micromustache","last_synced_at":"2026-02-19T08:38:43.616Z","repository":{"id":384804,"uuid":"14549781","full_name":"alexewerlof/micromustache","owner":"alexewerlof","description":"Ⓜ An extremely fast and small sub-implementation of the {{mustache}} template engine for JavaScript","archived":false,"fork":false,"pushed_at":"2025-12-15T20:08:14.000Z","size":2723,"stargazers_count":244,"open_issues_count":37,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-14T09:03:25.497Z","etag":null,"topics":["javascript","mustache","mustache-templates","mustachejs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/micromustache","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexewerlof.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":".github/SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"userpixel","open_collective":"alexewerlof"}},"created_at":"2013-11-20T07:33:54.000Z","updated_at":"2025-11-02T09:34:33.000Z","dependencies_parsed_at":"2023-07-05T14:44:47.511Z","dependency_job_id":null,"html_url":"https://github.com/alexewerlof/micromustache","commit_stats":{"total_commits":167,"total_committers":10,"mean_commits":16.7,"dds":0.5269461077844311,"last_synced_commit":"da3420db27b7a2fdfbb768811a1280b34952dc95"},"previous_names":["hanifbbz/micromustache","alexewerlof/micromustache","userpixel/micromustache"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/alexewerlof/micromustache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexewerlof%2Fmicromustache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexewerlof%2Fmicromustache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexewerlof%2Fmicromustache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexewerlof%2Fmicromustache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexewerlof","download_url":"https://codeload.github.com/alexewerlof/micromustache/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexewerlof%2Fmicromustache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29608657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T06:47:36.664Z","status":"ssl_error","status_checked_at":"2026-02-19T06:45:47.551Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mustache","mustache-templates","mustachejs"],"created_at":"2024-12-06T17:21:41.083Z","updated_at":"2026-02-19T08:38:43.586Z","avatar_url":"https://github.com/alexewerlof.png","language":"TypeScript","funding_links":["https://github.com/sponsors/userpixel","https://opencollective.com/alexewerlof","https://opencollective.com/micromustache"],"categories":["TypeScript"],"sub_categories":[],"readme":"[![Downloads](https://img.shields.io/npm/dm/micromustache.svg?style=flat-square)](http://npm-stat.com/charts.html?package=micromustache\u0026from=2017-01-01)\n[![GitHub stars](https://img.shields.io/github/stars/userpixel/micromustache?style=flat-square)](https://github.com/userpixel/micromustache/stargazers)\n[![Known Vulnerabilities](https://snyk.io/test/github/userpixel/micromustache/badge.svg?style=flat-square)](https://snyk.io/test/github/userpixel/micromustache)\n[![GitHub license](https://img.shields.io/github/license/userpixel/micromustache?style=flat-square)](https://github.com/userpixel/micromustache/blob/master/LICENSE.md)\n[![Version](https://img.shields.io/npm/v/micromustache.svg?style=flat-square)](http://npm.im/micromustache)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n[![GitHub issues](https://img.shields.io/github/issues/userpixel/micromustache.svg?style=flat-square)](https://github.com/userpixel/micromustache/issues)\n\n# micromustache\n\n![Logo](https://raw.github.com/userpixel/micromustache/master/logo.png)\n\nA **secure**, fast and lightweight template engine with some handy additions.\n\n⛹ Check out **[the playground](https://unpkg.com/micromustache/playground/index.html)**\n\nThink of it as a sweet spot between plain text interpolation and [mustache.js](https://github.com/janl/mustache.js); Certainly not as logic-ful as [Handlebars](http://handlebarsjs.com/)! Sometimes a stricter syntax is the right boundary to reduce potential errors and improve performance. This tool has a limited scope that doesn't attempt to solve everybody's use case, and instead do a specific thing well.\n\n* 🏃 Faster than MustacheJS (_Micromustache is the fastest template engine that doesn't need pre-compilation and still works in CSP environments_)\n* 🔒 **Secure** has limits for variable length, number of interpolations, nesting debth and common Javascript pitfalls (`__proto__`, `constructor`, getters/etc). Works in CSP environments (no usage of `eval()` or `new Function()`). Published only with 2FA.\n* ✏ **Bracket notation** support `a[1]['foo']` accessors (mustache.js/handlebar syntax of `a.1.foo` is also supported).\n* 🎈 **Lightweight** less than 350 source lines of code, easy to audit, small API surface, easy to pick up\n* 🏳 **No dependencies**\n* 🐁 **Small memory footprint** sane caching strategy, no memory leak\n* 🚩 **Meaningful errors** to improve developer experience. All functions test their input contracts and throw meaningful errors to improve developer experience (DX).\n* ⚡ **TypeScript** types included out of the box and updated with every version of the library\n* 🐇 Works in node (CommonJS) and Browser (UMD) and EcmaScript 6 Modules (ESM)\n* 🛠 Thoroughly tested (full test coverage over 120+ tests). Also tested to produce the same results as [Mustache.js](https://github.com/janl/mustache.js/).\n* 📖 Full JSDoc documentation\n\nIf variable interpolation is all you need, *micromustache* is a [drop-in replacement](src/mustachejs.spec.ts) for MustacheJS (see its differences with [Mustache.js](https://github.com/userpixel/micromustache/wiki/Differences-with-Mustache.js))\n\n[Try it in your browser!](https://npm.runkit.com/micromustache)\n\n# Getting started\n\nUse directly with [UNPKG](https://unpkg.com/browse/micromustache/):\n\n```javascript\nimport { render } from 'https://unpkg.com/browse/micromustache/dist/micromustache.mjs'\nconsole.log(render('Hello {{name}}!', { name: 'world' }))\n// Hello world!\n```\n\nInstall:\n\n```bash\n$ npm i micromustache\n```\n\nUse:\n\n```javascript\nconst { render } = require('micromustache')\nconsole.log(render('Hello {{name}}!', { name: 'world' }))\n// Hello world!\n```\n\nWhy not just use EcmaScript [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)?\n\nTemplate literals work great when the template and the variables are in the same scope but not so well when the template is in another scope or is not known ahead of time. For example, suppose you had a function like this:\n\n```javascript\nfunction greet(name) {\n  return `Hi ${name}!`\n}\n```\n\nAfter your function became successful and you got rich 🤑 you may decide to dominate the world and expand to new markets which speak other languages. You need to internationalize it. Adding one more language is easy:\n\n```javascript\nfunction greet(name, lang) {\n  // Note the lang parameter that contains a language code\n  return lang === 'sv' ? `Hej ${name}!` : `Hi ${name}!`\n}\n```\n\nBut how about a bunch of them?\n\n```javascript\nfunction greet(name, lang) {\n  switch (lang) {\n    case 'sv': return `Hej ${name}!`\n    case 'es': return `Hola ${name}!`\n    default:\n    case 'en': return `Hi ${name}!`\n  }\n}\n```\n\nThat doesn't scale well as you dominate country after country and need to support more languages! Besides, that's just one string! The main problem is that the content (the text) is coupled to the code (the variable interpolation). **Template engines** help you to move the content out of the function and let something else deal with that concern.\n\n```javascript\nconst { render } = require('micromustache')\n// A very simplified i18n database\nconst db = {\n  en: {\n    greeting: 'Hi {{name}}!',\n    // ...\n  },\n  sv: {\n    greeting: 'Hej {{name}}!',\n    // ...\n  },\n  // ...\n}\n\nfunction greet(name, lang) {\n  return render(db[lang].greeting, { name } )\n}\n```\n\nNow it's better! 😎 All the templates are together and they are easy to update and translate. By default, we use the popular syntax that encloses paths between double curly braces (`{{` and `}}`) but you can customize _micromustache_ if you prefer something else.\nJust like template literals, you can of course reference deep nested objects:\n\n```javascript\nconst { render } = require('micromustache')\nconst scope = {\n  fruits: [\n    { name: 'Apple', color: 'red' },\n    { name: 'Banana', color: 'yellow' },\n  ]\n}\nconsole.log(render('I like {{fruits[1].color}}!', scope))\n// I like Bababa!\n```\n\n*It worth to note that Mustache and Handlebars don't support `fruits[1].color` syntax and rather expect you to write it as `fruits.1.color`.*\n\nThe real power of micromustache comes from letting you resolve a path using your own functions! To pass a resolver function, you can use `renderFn()` instead of `render()`:\n\n```javascript\nconst { renderFn } = require('micromustache')\n// Just converts the path to upper case\nconst up = str =\u003e str.toUpperCase()\n\nconsole.log(renderFn('My name is {{Alex}}!', up))\n// My name is ALEX!\n```\n\nThe resolver gets the scope as its second parameter. If you want to lookup a value, there's a `get()` function as well:\n\n```javascript\nconst { renderFn, get } = require('micromustache')\n\n// Looks up the value and converts it to stars\nfunction star(path, scope) {\n  // path comes from the template and is 'password' here\n  // scope is { password: 'abc' }\n  const value = get(scope, path) // value is 'abc'\n  return '*'.repeat(value.length)\n}\n\nconsole.log(renderFn('My password is {{password}}!', star, { password: 'abc' }))\n// My password is ***!\n```\n\nIf you want to resolve a value asynchronously, we got you covered using the `renderFnAsync()` instead of `renderFn()`. For example the following code uses [node-fetch](https://www.npmjs.com/package/node-fetch) to resolve a url.\n\n```javascript\nconst { renderFnAsync } = require('micromustache')\nconst fetch = require('node-fetch')\n\nasync function taskTitleFromUrl(url) {\n  const response = await fetch(url)\n  const obj = await response.json()\n  return obj.title\n}\n\nconsole.log(await renderFnAsync('Got {{https://jsonplaceholder.typicode.com/todos/1}}!', fetch))\n// Got delectus aut autem!\n```\n\nIf you find yourself working on a particular template too often, you can `compile()` it once and cache the result so the future renders will be much faster. The compiler returns an object with `render()`, `renderFn()` and `renderFnAsync()` methods. The only difference is that they don't get the template and only need a scope:\n\n```javascript\nconst { compile } = require('micromustache')\nconst compiled = compile('Hello {{name}}! I am {{age}} years old!')\nconsole.log(compiled.render({ name: 'world', age: 42 }))\n// Hello world! I'm 42\n// The methods are bound so you can use the destructed version for brevity\nconst { render } = compile\nconsole.log(render({ name: 'world', age: 42 }))\n// Hello world! I'm 42\n```\n\n*If the `compiled` variable above is garbage collected, the cache is freed (unlike some other template engines that dearly keep hold of the compiled result in their cache which may leads to memory leaks or **out of memory errors** over longer usage).*\n\nUsing the options you can do all sorts of fancy stuff. For example, here is an imitation of the **C#** string interpolation syntax:\n\n```javascript\nconst { render } = require('micromustache')\nconst $ = scope =\u003e strings =\u003e render(strings[0], scope, { tags: ['{', '}'] })\n\nconst name = 'Michael'\nconsole.log($({ name })`Hello {name}!`)\n// Hello Michael!\n```\n\n# API\n\n[On Github pages](https://userpixel.github.io/micromustache/)\n\n# Examples\n\nCheck out the [`examples`](./examples) directory.\n_Note that they need you to build the project locally._\n\n# FAQ\n\n[On wiki](https://github.com/userpixel/micromustache/wiki/FAQ)\n\n# Known issues\n\n[On wiki](https://github.com/userpixel/micromustache/wiki/Known-issues)\n\n# License\n\n[MIT](./LICENSE.md)\n\n---\n\n_Made in Sweden 🇸🇪 by [@alexewerlof](https://mobile.twitter.com/alexewerlof)_\n\n\u003ca href=\"https://opencollective.com/micromustache\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://opencollective.com/micromustache/donate/button@2x.png?color=white\" width=300 /\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexewerlof%2Fmicromustache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexewerlof%2Fmicromustache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexewerlof%2Fmicromustache/lists"}