{"id":21283366,"url":"https://github.com/jg-rp/liquidscript","last_synced_at":"2025-07-11T11:30:51.386Z","repository":{"id":37703490,"uuid":"472418058","full_name":"jg-rp/liquidscript","owner":"jg-rp","description":"Liquid templates for JavaScript","archived":false,"fork":false,"pushed_at":"2024-07-16T12:19:28.000Z","size":13908,"stargazers_count":3,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-07T17:58:45.286Z","etag":null,"topics":["javascript","liquid","liquid-templating-engine","nodejs","templates","typescript"],"latest_commit_sha":null,"homepage":"https://jg-rp.github.io/liquidscript/","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/jg-rp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-21T16:18:47.000Z","updated_at":"2024-07-16T12:20:55.000Z","dependencies_parsed_at":"2024-07-14T17:34:40.903Z","dependency_job_id":"338b6d2c-262a-47c1-92cc-4a518558b96e","html_url":"https://github.com/jg-rp/liquidscript","commit_stats":{"total_commits":182,"total_committers":1,"mean_commits":182.0,"dds":0.0,"last_synced_commit":"70bbfbb4c752e5efa13479ecdd2b591d338f4fa4"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-rp%2Fliquidscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-rp%2Fliquidscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-rp%2Fliquidscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-rp%2Fliquidscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jg-rp","download_url":"https://codeload.github.com/jg-rp/liquidscript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225715889,"owners_count":17512909,"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":["javascript","liquid","liquid-templating-engine","nodejs","templates","typescript"],"created_at":"2024-11-21T11:08:03.533Z","updated_at":"2024-11-21T11:08:04.171Z","avatar_url":"https://github.com/jg-rp.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LiquidScript\n\nLiquid templates for JavaScript.\n\n[![npm version](https://img.shields.io/npm/v/liquidscript?style=flat-square)](https://www.npmjs.com/package/liquidscript)\n[![tests status](https://img.shields.io/github/actions/workflow/status/jg-rp/liquidscript/tests.yaml?branch=main\u0026label=tests\u0026style=flat-square)](https://github.com/jg-rp/liquidscript/actions/workflows/tests.yaml)\n\n```javascript\nimport { Template } from \"liquidscript\";\n\nconst template = Template.fromString(\"Hello, {{ you }}!\");\n\n// Sync\nconsole.log(template.renderSync({ you: \"World\" })); // Hello, World!\nconsole.log(template.renderSync({ you: \"Liquid\" })); // Hello, Liquid!\n\n// Async\ntemplate.render({ you: \"World\" }).then(console.log); // Hello, World!\ntemplate.render({ you: \"Liquid\" }).then(console.log); // Hello, Liquid!\n\n// Or, using await\n(async () =\u003e {\n  console.log(await template.render({ you: \"World\" })); // Hello, World!\n  console.log(await template.render({ you: \"Liquid\" })); // Hello, Liquid!\n})();\n```\n\n## Links\n\n- Documentation: https://jg-rp.github.io/liquidscript/\n- API documentation: https://jg-rp.github.io/liquidscript/api\n- Filter reference: https://jg-rp.github.io/liquidscript/language/filters\n- Tag reference: https://jg-rp.github.io/liquidscript/language/tags\n- Change log: https://github.com/jg-rp/liquidscript/blob/main/CHANGELOG.md\n- NPM: https://www.npmjs.com/package/liquidscript\n- Issue tracker: https://github.com/jg-rp/liquidscript/issues\n\n## Dependencies\n\nLiquidScript currently depends on [Decimal.js](https://mikemcl.github.io/decimal.js/) for decimal arithmetic, and [luxon](https://github.com/moment/luxon/) for timezone aware date/times and some limited parsing of date and time strings.\n\nBoth of these dependencies are considered an implementation detail and might be replace with lighter-weight alternatives later.\n\n## Supported Browsers and Environments\n\nLiquidScript is written in TypeScript, compiled to JavaScript using [Babel](https://babeljs.io/) and bundled using [Rollup](https://rollupjs.org/guide/en/). The following included bundles target `defaults, not IE 11, maintained node versions, not node 12`. See [Browserslist](https://github.com/browserslist/browserslist#browserslist-).\n\n| Bundle                            | Description                                                                                        |\n| --------------------------------- | -------------------------------------------------------------------------------------------------- |\n| `liquidscript.cjs.js`             | A CommonJS formatted bundle                                                                        |\n| `liquidscript.esm.js`             | An ECMAScript module formatted bundle                                                              |\n| `liquidscript.iife.bundle.js`     | A bundle formatted as an Immediately Invoked Function Expression, including dependencies.          |\n| `liquidscript.iife.bundle.min.js` | A minified bundle formatted as an Immediately Invoked Function Expression, including dependencies. |\n| `liquidscript.iife.js`            | A bundle formatted as an Immediately Invoked Function Expression, excluding dependencies.          |\n| `liquidscript.iife.min.js`        | A minified bundle formatted as an Immediately Invoked Function Expression, excluding dependencies. |\n\n## Why?\n\nSome excellent JavaScript implementations of Liquid already exist. To meet some rather specific requirements, LiquidScript has been developed with the following goals.\n\n### Project Goals\n\n- Maintain a very strict policy of compatibility with Ruby Liquid and, by extension, [Python Liquid](https://github.com/jg-rp/liquid). Given an equivalent render context, a template rendered with LiquidScript should produce the same output as when rendered with Ruby Liquid, and vice versa. See [golden-liquid](https://github.com/jg-rp/golden-liquid). Most notably:\n\n  - Floats with a single trailing zero must retain that zero upon output.\n  - Built-in math filters must handle integers and floats appropriately. For example, the `divided_by` filter should perform integer division if both arguments are integers, and regular division otherwise.\n  - Built-in math filters must do decimal arithmetic. See [Decimal.js dependency](#dependencies).\n  - Built-in filters must reject excess or otherwise invalid arguments with an error.\n\n- It should be possible to extend LiquidScript (without forking) to include features commonly found in other template languages. Like template inheritance, expressions that use logical `not` and inline conditional statements, for example.\n\n- Expose a syntax tree for every parsed template, facilitating template static analysis and performance optimizations.\n\n- Offer fine-grained control of template context globals. Pin globals to an environment, template or loader.\n\n- Offer an asynchronous API, including handling of render context promises and asynchronous drops.\n\n- Offer HTML and XML auto-escaping, with facilities to mark text as \"safe\". See [Auto Escape](https://jg-rp.github.io/liquidscript/introduction/auto-escape).\n\n- Drops (arbitrary objects added to a render context) must not expose their methods unless explicitly whitelisted. See [drop protocol](https://jg-rp.github.io/liquidscript/introduction/objects-and-drops#drop-protocol).\n\n## Benchmark\n\nYou can run the benchmark using `yarn benchmark` from the root of the source tree. On my development machine we get the following results.\n\n```plain\ntemplates per iteration: 60\nrounds (best of):        3\nsimulated IO time:       50ms\n\nparse ...\nrenderSync ...\nparse \u0026 renderSync ...\nrender ...\nrender + parse with IO ...\n\n                 parse:\t63.15   i/s - 300  in 4.75s\n            renderSync:\t213.65  i/s - 1000 in 4.68s\n    parse \u0026 renderSync:\t44.36   i/s - 250  in 5.64s\n                render:\t109.45  i/s - 500  in 4.57s\nrender + parse with IO:\t14.91   i/s - 50   in 3.35s\n```\n\nThe benchmark workload has been carefully matched to that of the [reference implementation](https://github.com/Shopify/liquid/tree/master/performance), although it's not clear what, if any, overhead their benchmark includes.\n\nWhen the same benchmark is run using [LiquidJS](https://github.com/harttle/liquidjs), it shows that, for parsing templates, LiquidJS is faster than LiquidScript, but LiquidScript is faster at rendering templates.\n\nCompared to [Python Liquid](https://github.com/jg-rp/liquid#benchmark), which includes a comparable benchmark, LiquidScript is as much as two or three times faster for synchronous operations. Python Liquid's benchmark does not currently include figures for asynchronously rendering templates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjg-rp%2Fliquidscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjg-rp%2Fliquidscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjg-rp%2Fliquidscript/lists"}