{"id":13491806,"url":"https://github.com/18alantom/strawberry","last_synced_at":"2025-04-12T14:56:55.127Z","repository":{"id":155315326,"uuid":"625164867","full_name":"18alantom/strawberry","owner":"18alantom","description":"Zero-dependency, build-free framework for the artisanal web.","archived":false,"fork":false,"pushed_at":"2023-10-23T05:54:29.000Z","size":546,"stargazers_count":673,"open_issues_count":5,"forks_count":15,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-04-14T06:55:31.952Z","etag":null,"topics":["frontend","javascript","library","web","webdev"],"latest_commit_sha":null,"homepage":"https://strawberry.quest","language":"HTML","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/18alantom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null}},"created_at":"2023-04-08T09:05:04.000Z","updated_at":"2024-04-05T15:12:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc9232a3-1be7-49b9-8563-ad7bf383edf3","html_url":"https://github.com/18alantom/strawberry","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/18alantom%2Fstrawberry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/18alantom%2Fstrawberry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/18alantom%2Fstrawberry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/18alantom%2Fstrawberry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/18alantom","download_url":"https://codeload.github.com/18alantom/strawberry/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248586249,"owners_count":21128997,"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":["frontend","javascript","library","web","webdev"],"created_at":"2024-07-31T19:01:00.396Z","updated_at":"2025-04-12T14:56:55.106Z","avatar_url":"https://github.com/18alantom.png","language":"HTML","readme":"\u003e [!IMPORTANT]\n\u003e\n\u003e After nearly 2 years of no commits. I've decided to archive Strawberry.\n\u003e Should you be curious enough to wonder why, here's a post on [why it started, why it stopped, any why the decision was made](https://18alan.space/posts/archiving-strawberry.html).\n\n\u003cdiv align=\"center\" markdown=\"1\"\u003e\n\n\u003cimg src=\"https://github.com/18alantom/strawberry/assets/29507195/9cb6a348-3b02-4de7-be62-ee85cf594871\" alt=\"strawberry logo\" width=\"720\"/\u003e\n\nZero-dependency, build-free framework for the artisanal web.\n\n[Website](https://strawberry.quest) · [How it works](https://18alan.space/posts/how-hard-is-it-to-build-a-frontend-framework.html) · [Docs](https://github.com/18alantom/strawberry/tree/main/docs)\n\n\u003c/div\u003e\n\n\u003e **Warning**\n\u003e\n\u003e Strawberry is in an experimental phase. Everything stated below works, but I\n\u003e am still figuring out the quickest and cleanest ways of doing things.\n\n---\n\n\u003e Seriously, another frontend framework?\n\nYes, but, Strawberry is not like the usual frontend-framework.\n\nIt doesn't have any dependencies. It doesn't need a build-step to run. It's\ntiny, less than 3KB when gzipped. Yet it does a lot of the core things the big,\nspangly frameworks can do.\n\n```html\n\u003c!-- Define Components --\u003e\n\u003ctemplate name=\"plum-p\"\u003e\n  \u003cp style=\"color: plum\"\u003e\u003cslot /\u003e\u003c/p\u003e\n\u003c/template\u003e\n\n\u003c!-- Initialize Strawberry --\u003e\n\u003cscript\u003e\n  const data = sb.init();\n\u003c/script\u003e\n\n\u003c!-- Use Components --\u003e\n\u003cplum-p sb-mark=\"message\"\u003e A plum colored p element! \u003c/plum-p\u003e\n\n\u003c!-- Dynamically Update Components --\u003e\n\u003cscript\u003e\n  data.message = 'Hello, World!';\n\u003c/script\u003e\n```\n\n[Here's](https://strawberry.quest/#inventory-example) a live example from\nthe website.\n\n---\n\n\u003cdiv align=\"center\" markdown=\"1\"\u003e\n\n**Index**\n\n[Installation](#installation) · [Features](#features) · [Examples](#examples) · [Development](#development)\n\n[Docs](https://github.com/18alantom/strawberry/tree/main/docs) · [Roadmap](https://github.com/18alantom/strawberry/blob/main/ROADMAP.md)\n\n\u003c/div\u003e\n\n**Documentation Index**\n\n1. [Installation](./docs/installation.md): explains how to pull Strawberry code into your web project.\n2. [Getting Started](./docs/getting_started.md): describes a simple example with code walk through.\n3. [Reactivity](./docs/reactivity/README.md): explains what is reactivity in Strawberry.\n   1. [Reactive Values](./docs/reactivity/reactive_values.md): explains keys and values of the reactive object.\n   2. [Mark (`sb-mark`)](./docs/reactivity/mark.md): explains how to mark an element to update along with data.\n   3. [Conditionals (`sb-if`, `sb-ifnot`)](./docs/reactivity/conditionals.md): explains how to render or hide an element when data changes to truthy or falsy.\n   4. [Computed](./docs/reactivity/computed.md): explains how to define reactive values that depend on other reactive values.\n   5. [Directives](./docs/reactivity/directives.md): explains how to extend Strawberry with custom directives.\n4. Composability (to be added)\n5. [API](./docs/api.md): lists all of Strawberry's defined directives and methods.\n\n## Installation\n\nIf you wanna try it out, then run this 👇 command to setup a simple _starter_ page.\n\n```bash\ncurl -so- https://raw.githubusercontent.com/18alantom/strawberry/main/setup.sh | bash\n```\n\nOr if you wanna just use it straight away, copy this 👇 script tag in the head of your html file:\n\n```html\n\u003cscript src=\"https://unpkg.com/sberry@0.0.3-alpha.0/dist/sb.min.js\"\u003e\u003c/script\u003e\n```\n\n## Features\n\nHere're are a few of its features:\n\n1. **Reactivity**: change your data and the UI updates.\n2. **Composability**: create and use components.\n3. **Build-free**: doesn't require a build-step. Link or [copy the lib](https://unpkg.com/sberry@0.0.3-alpha.0/dist/sb.min.js) and you're ready to go.\n4. **Zero Dependencies**: has no dependencies. Uses WebAPIs for everything.\n5. **Tiny**: [source code](https://github.com/18alantom/strawberry/blob/main/index.ts) is under 1000 CLOC.\n6. **No VDOM**: directly updates the DOM.\n\nStrawberry is and will be developed with these two hard constraints:\n\n1. Zero dependencies.\n2. No build step required to run it.\n\nOther than this, there is also a soft constraint of keeping the source code light.\n\n---\n\n## Examples\n\nHere are a couple of simple examples of a few things that Strawberry can do\nright now.\n\n**1. Basic Reactivity**: `innerText` is updated when `data.message` when\nis set.\n\n```html\n\u003cp sb-mark=\"message\"\u003ePlaceholder\u003c/p\u003e\n\n\u003cscript\u003e\n  data.message = 'Hello, Strawberry!';\n\u003c/script\u003e\n```\n\n**2. Computed Values**: `innerText` is updated with the computed value\n`data.countMessage` when `data.count` is updated.\n\n```html\n\u003cp sb-mark=\"countMessage\"\u003ePlaceholder\u003c/p\u003e\n\n\u003cscript\u003e\n  data.count = 0;\n  data.countMessage = () =\u003e `The count is: ${data.count}`;\n\n  data.count += 1;\n\u003c/script\u003e\n```\n\n**3. Conditional Rendering**: `p` is rendered only when `data.sayHi` is `true`.\n\n```html\n\u003ctemplate sb-if=\"sayHi\"\u003e\n  \u003cp\u003eHi!\u003c/p\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\n  data.sayHi = true;\n\u003c/script\u003e\n```\n\n**4. Looping**: `ul` is populated with `li` when `data.list` is set. `innerText`\nof the `li` are set from the list items.\n\n```html\n\u003cul\u003e\n  \u003cli sb-mark=\"list.#\"\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cscript\u003e\n  data.list = ['Strawberry', 'Mulberry', 'Raspberry'];\n\u003c/script\u003e\n```\n\n**5. Templates**: On running `sb.register`, the `red-p` element is defined and can be used.\n\n```html\n\u003ctemplate name=\"red-p\"\u003e\n  \u003cp style=\"color: red\"\u003e\u003cslot /\u003e\u003c/p\u003e\n\u003c/template\u003e\n\n\u003cred-p\u003eHi!\u003c/red-p\u003e\n```\n\n**5. External Templates**: Templates can be defined in external files. They are loaded and registered using `sb.load`.\n\n```html\n\u003cscript\u003e\n  sb.load('./templates.html');\n\u003c/script\u003e\n\n\u003cred-p\u003eHi!\u003c/red-p\u003e\n```\n\n**6. Nested Templates**: Templates can be nested, named slots can be used to\n\n```html\n\u003c!-- Blue H1 Template --\u003e\n\u003ctemplate name=\"blue-h1\"\u003e\n  \u003ch1 style=\"color: blue\"\u003e\u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n\u003c/template\u003e\n\n\u003c!-- Red P Template --\u003e\n\u003ctemplate name=\"red-p\"\u003e\n  \u003cp style=\"color: red\"\u003e\u003cslot\u003e\u003c/slot\u003e\u003c/p\u003e\n\u003c/template\u003e\n\n\u003c!-- Div Template using the above two --\u003e\n\u003ctemplate name=\"user-div\"\u003e\n  \u003cdiv\u003e\n    \u003cblue-h1\u003e\n      \u003cslot name=\"name\" /\u003e\n    \u003c/blue-h1\u003e\n    \u003cred-p\u003e\n      \u003cslot name=\"age\" /\u003e\n    \u003c/red-p\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cbody\u003e\n  \u003cuser-div\u003e\n    \u003cspan slot=\"name\" sb-mark=\"user.name\"\u003e\u003c/span\u003e\n    \u003cspan slot=\"age\" sb-mark=\"user.age\"\u003e\u003c/span\u003e\n  \u003c/user-div\u003e\n\u003c/body\u003e\n\n\u003cscript\u003e\n  data.user = { name: 'Lin', age: 36 };\n\u003c/script\u003e\n```\n\n---\n\n## Development\n\nThe development of Strawberry does has a direction, but no deadlines as I work\non this usually during the weekends.\n\nHere's a\n[road map](https://github.com/18alantom/strawberry/blob/main/ROADMAP.md). This\nisn't exactly a road map, but a list of problems and maybe their solutions that\nneed to be implemented to further Strawberry.\n\n### Running Dev Mode\n\nStrawberry has only two dev dependencies: `esbuild` and `typescript`.\n\nTo run Strawberry in dev mode:\n\n```bash\n# Clone the repo\ngit clone https://github.com/18alantom/strawberry\n\n# Install esbuild and typescript\ncd strawberry\nyarn install\n\n# Run in Dev mode\nyarn dev\n```\n\nYou can now create an HTML file in the repository and add `script:src` to link\nthe generated `index.js` file. You can serve this using the Live Preview plugin.\n\nTo view the rendered HTML you need to serve it locally for that you can use the [Live Preview](https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server) VSCode plugin, or run [this](https://docs.python.org/3/library/http.server.html#:~:text=python%20%2Dm%20http.server%20%2D%2Dbind%20127.0.0.1):\n\n```bash\n# Cd into strawberry root\ncd strawberry\n\n# Run simple python server to serve files in strawberry\npython -m http.server 8080 --bind 127.0.0.1\n```\n\n### Tests\n\nRight now tests just involve linking strawberry to an html file (`test.*.html`),\nand calling the `test` function to check whether a value is as expected. Success\nand Failures are printed in the console.\n\nSee [`test.html`](https://github.com/18alantom/strawberry/blob/main/tests/test.html) for an example.\n\nTo see all tests in one place, open `test/index.html`.\n\n### Website\n\nThe website has two dependencies required to run, `sb.min.js` and\n`highlight.min.js` for running strawberry in the example and highlighting all the code.\n\nYou can run the [`pubwebsite.sh`](https://github.com/18alantom/strawberry/blob/main/pubwebsite.sh) script which downloads these files:\n\n```bash\n./pubwebsite.sh\n```\n\nAnd then respond with `\"n\"` when it asks to publish:\n\n```bash\n$ Publish the website? [y/n]: n\n$ /Users/you/Desktop/projects/strawberry\n```\n\nAfter the script has run, [`website/index.html`](https://github.com/18alantom/strawberry/blob/main/website/index.html) should render as expected.\n\n---\n\n## Douglas Crockford on the XML of today\n\nThese are excerpts from the CoRecursive podcast on [JSON vs XML](https://corecursive.com/json-vs-xml-douglas-crockford/).\n\n\u003e It’s probably the JavaScript frameworks. They have gotten so big and so weird.\n\u003e People seem to love them. I don’t understand why.\n\nAnd on web APIs.\n\n\u003e ...the browsers have actually gotten pretty good. The web standards thing have\n\u003e finally worked, and the web API is stable pretty much. Some of it’s still pretty\n\u003e stupid, but it works and it’s reliable.\n\nRead the transcript on [CoRecursive](https://corecursive.com/json-vs-xml-douglas-crockford/#javascript-frameworks).\n","funding_links":[],"categories":["HTML"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F18alantom%2Fstrawberry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F18alantom%2Fstrawberry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F18alantom%2Fstrawberry/lists"}