{"id":22660759,"url":"https://github.com/buxlabs/boxwood","last_synced_at":"2025-04-09T07:07:41.854Z","repository":{"id":43842370,"uuid":"127563817","full_name":"buxlabs/boxwood","owner":"buxlabs","description":"Server side templating engine written in JavaScript","archived":false,"fork":false,"pushed_at":"2024-09-13T07:50:03.000Z","size":4345,"stargazers_count":136,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-01T07:39:45.819Z","etag":null,"topics":["javascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/buxlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":"emilos"}},"created_at":"2018-03-31T19:23:33.000Z","updated_at":"2024-09-13T07:50:06.000Z","dependencies_parsed_at":"2024-03-26T10:52:09.381Z","dependency_job_id":"fdd8dbee-0e96-4fbe-ac84-513f547d275c","html_url":"https://github.com/buxlabs/boxwood","commit_stats":{"total_commits":1698,"total_committers":9,"mean_commits":"188.66666666666666","dds":"0.44464075382803303","last_synced_commit":"89601a71c6b83153ffcd55562b70da8fc9aad5fc"},"previous_names":["buxlabs/pure-engine","buxlabs/html-engine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buxlabs%2Fboxwood","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buxlabs%2Fboxwood/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buxlabs%2Fboxwood/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buxlabs%2Fboxwood/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buxlabs","download_url":"https://codeload.github.com/buxlabs/boxwood/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247994121,"owners_count":21030050,"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"],"created_at":"2024-12-09T11:11:57.249Z","updated_at":"2025-04-09T07:07:41.834Z","avatar_url":"https://github.com/buxlabs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/emilos"],"categories":[],"sub_categories":[],"readme":"# boxwood\n\n[![npm](https://img.shields.io/npm/v/boxwood.svg)](https://www.npmjs.com/package/boxwood)\n[![build](https://github.com/buxlabs/boxwood/workflows/build/badge.svg)](https://github.com/buxlabs/boxwood/actions)\n\n\u003e Server side templating engine written in JavaScript\n\n[boxwood](https://github.com/buxlabs/boxwood) was created to achieve the following design goals:\n\n1. templates can be split into components\n2. css is hashed per component\n3. css is automatically minified\n4. critical css is inlined\n5. templates can import other dependencies\n6. inline images or svgs\n7. i18n support\n8. server side\n9. good for seo\n10. small (1 file, 700 LOC~)\n11. easy to start, familiar syntax\n12. easy to test\n\nThe template starts with a standard js file, which builds a tree of nodes, that get rendered to html.\n\n## Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [Syntax](#syntax)\n- [Maintainers](#maintainers)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Install\n\n`npm install boxwood`\n\n## Usage\n\n```js\nconst { compile } = require(\"boxwood\")\nconst { join } = require(\"path\")\n// ...\nconst path = join(__dirname, \"index.js\")\nconst { template } = compile(path)\n// ...\nconst html = template({ foo: \"bar\" })\nconsole.log(html)\n```\n\nYou can use [express-boxwood](https://www.npmjs.com/package/express-boxwood) for [express](https://www.npmjs.com/package/express).\n\n## Syntax\n\n```js\n// example/index.js\nconst layout = require(\"./layout\")\nconst banner = require(\"./banner\")\n\nmodule.exports = () =\u003e {\n  return layout({ language: \"en\" }, [\n    banner({\n      title: \"Hello, world!\",\n      description: \"Lorem ipsum dolor sit amet\",\n    }),\n  ])\n}\n```\n\n```js\n// example/layout/index.js\nconst { component, css, doctype, html, body } = require(\"boxwood\")\nconst head = require(\"./head\")\n\nconst styles = css.load(__dirname)\n\nmodule.exports = component(\n  ({ language }, children) =\u003e {\n    return [\n      doctype(),\n      html({ lang: language }, [\n        head(),\n        body({ className: styles.layout }, children),\n      ]),\n    ]\n  },\n  { styles }\n)\n```\n\n```js\n// example/layout/head/index.js\nconst { head, title } = require(\"boxwood\")\n\nmodule.exports = () =\u003e {\n  return head([title(\"example\")])\n}\n```\n\n```js\n// example/banner/index.js\nconst { component, css, h1, p, section } = require(\"boxwood\")\n\nconst styles = css.load(__dirname)\n\nmodule.exports = component(\n  ({ title, description }) =\u003e {\n    return section({ className: styles.banner }, [\n      h1(title),\n      description \u0026\u0026 p(description),\n    ])\n  },\n  { styles }\n)\n```\n\n```js\n// example/banner/index.test.js\nconst test = require(\"node:test\")\nconst assert = require(\"node:assert\")\nconst { compile } = require(\"boxwood\")\n\ntest(\"banner renders a title\", async () =\u003e {\n  const { template } = compile(__dirname)\n  const html = template({ title: \"foo\" })\n  assert(html.includes(\"\u003ch1\u003efoo\u003c/h1\u003e\"))\n})\n\ntest(\"banner renders an optional description\", async () =\u003e {\n  const { template } = compile(__dirname)\n  const html = template({ title: \"foo\", description: \"bar\" })\n  assert(html.includes(\"\u003ch1\u003efoo\u003c/h1\u003e\"))\n  assert(html.includes(\"\u003cp\u003ebar\u003c/p\u003e\"))\n})\n```\n\nYou can check the `test` dir for more examples.\n\n## Maintainers\n\n[@emilos](https://github.com/emilos)\n\n## Contributing\n\nAll contributions are highly appreciated. Please feel free to open new issues and send PRs.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuxlabs%2Fboxwood","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuxlabs%2Fboxwood","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuxlabs%2Fboxwood/lists"}