{"id":21701641,"url":"https://github.com/flintinatux/puddles","last_synced_at":"2025-07-21T08:02:47.127Z","repository":{"id":65478534,"uuid":"66240347","full_name":"flintinatux/puddles","owner":"flintinatux","description":"Tiny vdom app framework. Pure Redux. No boilerplate.","archived":false,"fork":false,"pushed_at":"2019-05-24T14:01:27.000Z","size":416,"stargazers_count":25,"open_issues_count":0,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-06-18T11:55:09.623Z","etag":null,"topics":["frontend-framework","functional-programming","reducer","redux","vdom","virtual-dom"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/flintinatux.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":"2016-08-22T04:46:45.000Z","updated_at":"2021-04-29T03:35:04.000Z","dependencies_parsed_at":"2023-01-25T07:45:24.690Z","dependency_job_id":null,"html_url":"https://github.com/flintinatux/puddles","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/flintinatux/puddles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Fpuddles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Fpuddles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Fpuddles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Fpuddles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flintinatux","download_url":"https://codeload.github.com/flintinatux/puddles/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Fpuddles/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266248501,"owners_count":23899056,"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-framework","functional-programming","reducer","redux","vdom","virtual-dom"],"created_at":"2024-11-25T20:24:56.745Z","updated_at":"2025-07-21T08:02:47.106Z","avatar_url":"https://github.com/flintinatux.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"#\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/888052/31304037-9a1d36ba-aae6-11e7-913e-8cb5d61c561a.png\" alt=\"puddles\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  Pure Redux. No boilerplate.\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/puddles\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/puddles.svg\" alt=\"npm version\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/puddles\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/puddles.svg\" alt=\"npm downloads\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"#\"\u003e\u003cimg src=\"https://img.shields.io/badge/gzip--size-7.24%20kB-blue.svg\" alt=\"gzip-size\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003cbr /\u003e\n  \u003ca href=\"https://travis-ci.org/flintinatux/puddles\"\u003e\u003cimg src=\"https://travis-ci.org/flintinatux/puddles.svg?branch=master\" alt=\"Build Status\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/flintinatux/puddles?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/flintinatux/puddles/badge.svg?branch=master\" alt=\"Coverage Status\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n\n## Introduction\n\nThe main goal of `puddles` is to make the [Redux](http://redux.js.org/) pattern easy, without all of the boilerplate.  If you like the Redux pattern, but wish you could code it in a more functional style, then `puddles` is for you.\n\nWith `puddles` you get all of these for free:\n\n- curried [action creators](https://github.com/flintinatux/puddles/blob/master/docs/API.md#paction)\n- switch-free [reducer construction](https://github.com/flintinatux/puddles/blob/master/docs/API.md#phandle)\n- dead simple [reducer composition](https://github.com/flintinatux/puddles/blob/master/docs/API.md#pmount)\n- pure view functions in [plain javascript](https://github.com/flintinatux/puddles/blob/master/docs/API.md#p)\n- modern [client-side routing](https://github.com/flintinatux/puddles/blob/master/docs/API.md#pmount) with `history.pushState`\n- native support for [thunks](https://github.com/flintinatux/puddles/blob/master/docs/API.md#pmount)\n- [automatically dispatched](https://github.com/flintinatux/puddles/blob/master/docs/API.md#pmount) user actions\n- integration with the [Redux DevTools extension](https://github.com/flintinatux/puddles/blob/master/docs/API.md#pmount)\n\nTo whet your appetite, try the obligatory Hello World example:\n\n```js\nconst { compose, constant, merge, path } = require('tinyfunk')\nconst p = require('puddles')\n\nconst actions = {\n  reset:   constant(p.action('RESET', null)),\n  setName: p.action('SET_NAME')\n}\n\nconst reducers = {\n  name: p.handle('world', {\n    RESET:    constant('world'),\n    SET_NAME: (state, name) =\u003e merge(state, { name })\n  })\n}\n\nconst targetVal = path(['target', 'value'])\n\nconst view = (actions, state) =\u003e {\n  const { reset, setName } = actions\n  const { name } = state\n\n  return p('div#root', [\n    p('div.greeting', `Hello ${name}!`),\n\n    p('input.name', {\n      attrs: { placeholder: 'Enter name...' },\n      on: { input: compose(setName, targetVal) },\n      props: { value: name }\n    }),\n\n    p('button.reset', { on: { click: reset } }, 'Reset')\n  ])\n}\n\nconst root = document.getElementById('root')\n\np.mount({ actions, reducers, root, view })\n```\n\nNotice anything missing?  There is no `dispatch` function!  The `setName` action creator attached to the `input` event is composed with the `dispatch` function internally.\n\nImpressed?  Read the [full documentation](https://github.com/flintinatux/puddles/blob/master/docs/API.md) to learn more.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflintinatux%2Fpuddles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflintinatux%2Fpuddles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflintinatux%2Fpuddles/lists"}