{"id":34668337,"url":"https://github.com/pre63/lift.js","last_synced_at":"2026-05-27T10:31:23.737Z","repository":{"id":57290166,"uuid":"71180554","full_name":"pre63/lift.js","owner":"pre63","description":"lift.js is a compact monad opinionated javascript framework","archived":false,"fork":false,"pushed_at":"2016-12-31T22:05:22.000Z","size":68,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-03-03T00:39:56.661Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":false,"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/pre63.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}},"created_at":"2016-10-17T20:57:06.000Z","updated_at":"2020-11-12T16:53:37.000Z","dependencies_parsed_at":"2022-08-25T07:41:10.372Z","dependency_job_id":null,"html_url":"https://github.com/pre63/lift.js","commit_stats":null,"previous_names":["atomable/lift.js"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pre63/lift.js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pre63%2Flift.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pre63%2Flift.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pre63%2Flift.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pre63%2Flift.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pre63","download_url":"https://codeload.github.com/pre63/lift.js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pre63%2Flift.js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33562772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":"2025-12-24T19:42:51.810Z","updated_at":"2026-05-27T10:31:23.732Z","avatar_url":"https://github.com/pre63.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![atomable](https://img.shields.io/badge/atomable.io--blue.svg)](http://atomable.io)\r\n[![Build Status](https://travis-ci.org/atomable/lift.js.svg?branch=master)](https://travis-ci.org/atomable/lift.js)\r\n# lift.js — Write less code.\r\n\r\n## Introduction\r\nlift.js is a compact monad opinionated javascript library. It implements `Just` (Identity), `Maybe`, `Valid` (Validation) and a nice `Monad` factory. The `unit` comes with a `lift` function so you can add functionnality later in code to your monad. It's ment to be flexible and simple to use. It's written with es6 so it's less than 100 lines.\r\n\r\n## Installation\r\n### [npm](https://www.npmjs.com/package/liftjs)\r\n```\r\nnpm install liftjs\r\n```\r\n### [yarn](https://yarnpkg.com/)\r\n```\r\nyarn add liftjs\r\n```\r\n\r\n## Source code | fork | pull request | issues\r\nhttps://github.com/atomable/lift.js\r\n\r\n## Importing\r\n\r\nAll the following work, pick your demon. `lift.js` can be required directly for es next project or you can use the `lift-min.js` for all legacy applications.\r\n\r\n```javascript\r\nvar lift = require('liftjs');\r\n\r\nconst lift = require('liftjs');\r\n\r\nimport lift from 'liftjs';\r\n\r\nimport { Monad, Just, Maybe, Valid, Curry } from 'liftjs';\r\n```\r\n\r\n\r\n## Monad Factory\r\n```\r\nMonad(modifier[monad, value]: null) : unit\r\n```\r\n```javascript\r\nconst Person = Monad();\r\nconst person = Person({ firstname: 'Bill', lastname: 'Murray' });\r\n\r\n// with a modifier\r\nconst doubleIt = Monad((monad, value) =\u003e {\r\n  monad.double = value * 2;\r\n});\r\n\r\nconst two = doubleIt(2);\r\ntwo.double();\r\n// 4\r\n\r\n```\r\n\r\n## lift\r\n\r\nWith the `lift` function you can add function at any time on the monads.\r\n\r\n```\r\nMonad[A].lift[name, func[A] : Monad[A]];\r\n```\r\n```javascript\r\nconst justWithLog = Just(5);\r\nJust.lift('log', console.log);\r\njustWithLog.log();\r\n// console\u003e 5\r\n```\r\n\r\nYou can also use it on your custom monads.\r\n\r\n```javascript\r\nconst Person = Monad();\r\nconst person = Person({ firstname: 'Bill', lastname: 'Murray' });\r\n\r\nconst FullName = Monad();\r\nPerson.lift('compose', person =\u003e FullName(`${person.firstname}, ${person.lastname}`));\r\n\r\nperson.compose().run(console.log);\r\n// console\u003e Bill, Murray\r\n```\r\n\r\n## Just\r\n\r\n`Just` is an implementaion of the `Identity` monad. It's called `Just` because an 8 character variable is just too long.\r\n\r\n**The folowing function are available on `Just`, `Maybe`, `Valid`.**\r\n\r\n### bind, alias: chain\r\n```\r\nMonad[A].bind[func[A] : Monad[B], args] : Monad[B]\r\n```\r\n```javascript\r\nconst justWithValue = Just(5).bind((value)=\u003e Just(value));\r\n\r\n// Just[5]\r\n```\r\n\r\n### of\r\n```\r\nMonad[A].of[B] : Monad[B]\r\n```\r\n```javascript\r\nconst justWithValue = Just(5).of(6);\r\n// Just[6]\r\n\r\nconst justWithValue = Just(5).of(Just(6));\r\n// Just[6]\r\n```\r\n\r\n### get\r\n```\r\nMonad[A].get[] : A\r\n```\r\n```javascript\r\nconst value = Just(5).get();\r\n// 5\r\n```\r\n\r\n### map\r\n```\r\nMonad[A].map[func[A] : B ] : Monad[B]\r\n```\r\n```javascript\r\nconst justWithValue = Just(7).map(value =\u003e value * 2);\r\n// Just[14]\r\n```\r\n\r\n### join\r\n```\r\nMonad[Monad[A]].join[] : Monad[A]\r\n```\r\n```javascript\r\nconst justWithValue = Just(Just(5)).join()\r\n// Just[5]\r\n```\r\n### toMaybe\r\n```\r\nMonad[A].toMaybe[] : Maybe[A]\r\n```\r\n```javascript\r\nconst maybeWithValue = Just(5).toMaybe();\r\n// Maybe[5]\r\n```\r\n\r\n### run\r\n```\r\nMonad[A].run[func[A] : null]: Monad[A]\r\n```\r\n```javascript\r\nJust(5).run(value =\u003e console.log(value));\r\n// console\u003e 5\r\n```\r\n\r\n## Maybe\r\n\r\n###\r\n```\r\nMaybe(A) : Maybe[A]\r\n```\r\n```javascript\r\nconst maybeWithoutValue = Maybe()\r\n// Maybe[]\r\n\r\nconst maybeWithValue = Maybe(2)\r\n// Maybe[2]\r\n\r\nconst maybeWithoutValue = Maybe(undefined)\r\n// Maybe[]\r\n\r\nconst maybeWithoutValue = Maybe(null)\r\n// Maybe[]\r\n```\r\n\r\n### isNothing\r\n```\r\nMaybe[A].isNothing[] : boolean\r\n```\r\n```javascript\r\nconst value = Maybe(5).isNothing();\r\n// false\r\n\r\nconst value = Maybe(5).n();\r\n// false\r\n```\r\n\r\n### is\r\n```\r\nMaybe[A].is[] : boolean\r\n```\r\n```javascript\r\nconst value = Maybe(5).is();\r\n// true\r\n\r\nconst value = Maybe(5).i();\r\n// true\r\n```\r\n\r\n### or\r\n```\r\nMaybe[A].or[B] : A or B\r\n```\r\n```javascript\r\nconst maybeWithValue = Maybe().or(15);\r\n// 15\r\n```\r\n\r\n### else\r\n```\r\nMaybe[A].else[Monad[B]] : Maybe[A] or Monad[B]\r\n```\r\n```javascript\r\nconst maybeWithValue = Maybe(5).else(Maybe(15));\r\n// Maybe[5]\r\n\r\nconst maybeWithValue = Maybe().e(Just(15));\r\n// Just[15]\r\n```\r\n\r\n## IO\r\n\r\n###\r\n```\r\nIO(func[A]: B) : func[A] : IO[B]\r\n```\r\n```javascript\r\nconst appleIO = IO((num) =\u003e num + ' apple');\r\nappleIO(4);\r\nappleIO.run();\r\n// apple\r\n\r\nconst randomIO = IO(() =\u003e Math.random());\r\nrandomIO()\r\n  .run();\r\n// 0.12701886093193782\r\n\r\nconst writeFile  = IO((file, contents) =\u003e  fs.writeFileSync(file, contents, 'UTF-8'));\r\nrandomIO('/file.json', JSON.strigify({ monads : 'are awesome' }));\r\n  .run();\r\n// file is written to disk sync\r\n```\r\n\r\n## Curry\r\n`Curry` is a factory that takes a function and returs a curried function.\r\n```\r\nCurry(func) : func\r\n```\r\n\r\n```javascript\r\nconst curried = Curry((a, b) =\u003e a * b);\r\ncurried(3)(6);\r\n// 18\r\n\r\nCurry((a, b, c) =\u003e a + b + c)(1, 2, 3)\r\n// 6\r\n```\r\n\r\n## Roadmap\r\n\r\nI don't plan on adding all the typical monads to the library, if you feel one should be added you are welcome to make a pull request or to fork. I'm thinking of Free and List, but not sure yet. It will depend on what I use in my own projects.\r\n\r\nBelow are the things that I actually plan on doing. Soon.\r\n\r\n- document `Valid`\r\n- document `lift_value` function\r\n- document `method` function\r\n- add List monad\r\n- `ap` function just `Just` and `Maybe` \u0026 tests\r\n- tests for lift functions\r\n\r\n\r\n## Change Log\r\n - 1.2.0 : I've changed the Maybe api qute a bit, orSome, orElse, none, are replaced.\r\n\r\n## Links\r\n\r\n- [npm](https://www.npmjs.com/package/liftjs)\r\n- [atomable](http://www.atomable.io)\r\n- [@pre63](http://twitter.com/pre63)\r\n\r\n## Author\r\n\r\nWritten and maintained by [pre63](http://twitter.com/pre63).\r\n\r\nSponsored by [atomable](https://atomable.io).\r\n\r\nBased on [Douglas Crockford MONAD](https://github.com/douglascrockford/monad/blob/master/monad.js).\r\n\r\nSpecial thanks to [Monet](https://github.com/cwmyers/monet.js) for the inspiration.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpre63%2Flift.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpre63%2Flift.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpre63%2Flift.js/lists"}