{"id":19281265,"url":"https://github.com/zouloux/stach","last_synced_at":"2025-07-25T11:34:49.084Z","repository":{"id":45719840,"uuid":"514216491","full_name":"zouloux/stach","owner":"zouloux","description":"Minuscule mustache-like string templating system for node or browsers.","archived":false,"fork":false,"pushed_at":"2022-08-05T08:29:50.000Z","size":35,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-05T16:45:47.128Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zouloux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-15T09:46:39.000Z","updated_at":"2024-09-13T04:01:35.000Z","dependencies_parsed_at":"2022-09-26T21:30:27.191Z","dependency_job_id":null,"html_url":"https://github.com/zouloux/stach","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zouloux%2Fstach","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zouloux%2Fstach/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zouloux%2Fstach/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zouloux%2Fstach/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zouloux","download_url":"https://codeload.github.com/zouloux/stach/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240385750,"owners_count":19793064,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-09T21:22:10.837Z","updated_at":"2025-02-23T22:19:11.487Z","avatar_url":"https://github.com/zouloux.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# stach\n\n__Stach__ is a ![](./bits/stach.es2017.min.js.svg) __mustache-like__ string __templating__ system for __Node__ or __Browsers__.\n\n```typescript\nimport { Stach } from \"stach\"\n\nconst templated = Stach(\"Hello {{name}} 😸\", {name: \"mr Bond\"})\nconsole.log( templated ) // Hello mr Bond 😸\n```\n\n## Concept\n\nWhy do we need __Stach__ with literal template strings available everywhere ?\nStach can be useful when any **small templating** is needed when **the template source is not coming from javascript** itself.\n\u003cbr\u003eFor example, if you need to __process a template__ from a __user generated file__, __a dictionary__, or any other kind of input.\n\nStach is ultra-lightweight and compatible with Node and Browsers environments.\nIt uses Javascript's Regex based `String.replace` function to be **super effective**.\nIt's also compatible with multiline files / inputs.\nTypescript definitions are included ✌️\n\n### Scope\n\nStach can do __variable replacement__, __function calls__, and __short ternary evaluations__. **THAT'S IT.**\u003cbr\u003e\nIt **cannot** do advanced conditions, listing, HTML transformations, etc...\nIf you need all of this, check others template engines like [Mustache](https://mustache.github.io/), [Handlebars](https://handlebarsjs.com/) or even [React JSX](https://fr.reactjs.org/docs/introducing-jsx.html) in some cases.\n\n### Installation\n\nTo install Stach in your project :\u003cbr\u003e\n- NPM : `npm install stach`\n- Yarn : `yarn add stach`\n\n### Usage\n\nIf you are using CommonJS syntax :\n```javascript\nconst { Stach } = require('stach')\n```\n\nBetter, if ES-Modules syntax is available :\n```javascript\nimport { Stach } from 'stach'\n```\n\n### Simple variable replacement\n\n```javascript\nStach('Hello {{username}}', {\n    username: 'James Bond'\n});\n// 'Hello James Bond'\n```\n\n### Values can be functions\n\n```javascript\nconst user = { balance : 12 };\nStach('Your current balance is {{balance}}€', {\n    balance: () =\u003e user.balance\n});\n// 'Your current balance is 12€'\n```\n\n### Ternary conditions can be used :\n\n```javascript\nStach('Condition is {{test ? truthy : falsy}}', {\n    test: 0\n});\n// 'Condition is falsy'\n```\n\n### Or, with the help of functions :\n```javascript\nStach('{{name}} is {{age}} {{isAgePlural ? years : year}} old', {\n    name: 'Brad Pitt',\n    age: 55,\n    // Note that v here is the current value object\n    // So we can access dynamically to the age property\n    isAgePlural: v =\u003e v.age \u003e 1\n});\n// 'Brad Pitt is 55 years old'\n```\n\n### More functions\n\n```javascript\nStach('{{plainFunction}} == 15', {\n    value: 15,\n\t// This works\n    plainFunction () {\n        return this.value;\n    }\n});\n// '15 == 15'\n```\n\n### Complex example mixing functions and ternaries\n\n```javascript\nconst user = {\n    name: 'James Bond',\n    gender: 'male',\n    balance: 15\n}\nStach('Hello {{ isMale ? mr : mrs }} {{ getLastName }}. Your balance is {{ balance }}€.', {\n  ...user,\n  isMale: v =\u003e v.gender == 'male',\n  getLastName: v =\u003e v.name.split(' ')[1]\n});\n// 'Hello mr Bond. Your balance is 15€.'\n```\n\n### Advanced, delimiters regex can be changed\n\nHere is the default delimiter regex : `/{{(.*?)}}/gm` [see](https://github.com/zouloux/stach/blob/main/src/stach.ts#L5)\n\nThis will set delimiters from `{{var}}` to `{var}`.\nUse [regexr.com](https://regexr.com) to create easily your delimiter's Regex.\n\n```javascript\nconst singleCurlyRegex = /{(.*?)}/gm \t// regex for single curly braces\nconst template = 'Hello { username }' \t// template using single curly braces\nconst data = { username: 'Mr Bond' }\nStach( template, data, singleCurlyRegex ); // \"Hello Mr Bond\" \n```\n\n### Unpkg\n\nStach is available on [unpkg](https://unpkg.com/stach)\n\nUsage :\n```html\n\u003cscript src=\"https://unpkg.com/stach@1.0.0/dist/stach.es2017.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n\tStach(\"Hello from {{name}} !\", { name: 'unpkg' })\n\u003c/script\u003e\n```\n\n### Built\n\n__Stach__ is built from __typescript__ thanks to [tsbundle](https://github.com/zouloux/tsbundle)\n\n### TODO / Not working\n\nWe need a way to escape `{{` when templating code-like files or simply keep not found variables.\n\nEx :\n```typescript\nconst source = `\n\t...\n\tconst Test{{FileName}} = \"Source {{doNotReplace}}\"\n\t...\n`\nStach( source, {\n\tFileName : \"Replace\" \n})\n```\nwill try to replace `{{doNotReplace}}` which is something to keep in output.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzouloux%2Fstach","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzouloux%2Fstach","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzouloux%2Fstach/lists"}