{"id":23364455,"url":"https://github.com/fission-codes/webnative-elm","last_synced_at":"2025-12-11T20:56:33.778Z","repository":{"id":52218770,"uuid":"327039977","full_name":"fission-codes/webnative-elm","owner":"fission-codes","description":"Thin wrapper around webnative for Elm.","archived":false,"fork":false,"pushed_at":"2023-02-01T18:09:38.000Z","size":151,"stargazers_count":13,"open_issues_count":9,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-10-02T00:58:53.153Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://package.elm-lang.org/packages/fission-suite/webnative-elm/latest/","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fission-codes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-05T15:27:48.000Z","updated_at":"2024-02-07T10:53:25.000Z","dependencies_parsed_at":"2023-02-17T09:16:13.114Z","dependency_job_id":null,"html_url":"https://github.com/fission-codes/webnative-elm","commit_stats":null,"previous_names":["fission-suite/webnative-elm"],"tags_count":10,"template":false,"template_full_name":"fission-codes/project-template","purl":"pkg:github/fission-codes/webnative-elm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fwebnative-elm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fwebnative-elm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fwebnative-elm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fwebnative-elm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fission-codes","download_url":"https://codeload.github.com/fission-codes/webnative-elm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fwebnative-elm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27670064,"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","status":"online","status_checked_at":"2025-12-11T02:00:11.302Z","response_time":56,"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":"2024-12-21T13:16:11.831Z","updated_at":"2025-12-11T20:56:33.745Z","avatar_url":"https://github.com/fission-codes.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://webnative.dev/webnative-full.svg\" width=\"230\" /\u003e\n\n[![Built by FISSION](https://img.shields.io/badge/⌘-Built_by_FISSION-purple.svg)](https://fission.codes)\n[![Discord](https://img.shields.io/discord/478735028319158273.svg)](https://discord.gg/zAQBDEq)\n[![Discourse](https://img.shields.io/discourse/https/talk.fission.codes/topics)](https://talk.fission.codes)\n\n**A thin wrapper around [Webnative](https://github.com/fission-codes/webnative#readme) for Elm.**\n\nThe Webnative SDK empowers developers to build fully distributed web applications without needing a complex back-end. The SDK provides:\n\n- **User accounts** via the browser's [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) or by using a blockchain wallet as a [webnative plugin](https://github.com/fission-codes/webnative-walletauth).\n- **Authorization** using [UCAN](https://ucan.xyz/).\n- **Encrypted file storage** via the [Webnative File System](https://guide.fission.codes/developers/webnative/file-system-wnfs) backed by [IPLD](https://ipld.io/).\n- **Key management** via websockets and a two-factor auth-like flow.\n\nWebnative applications work offline and store data encrypted for the user by leveraging the power of the web platform. You can read more about Webnative in Fission's [Webnative Guide](https://guide.fission.codes/developers/webnative). There's also an API reference which can be found at [webnative.fission.app](https://webnative.fission.app)\n\n\n\n# QuickStart\n\n```shell\nelm install fission-codes/webnative-elm\n\n# requires webnative version 0.36 or later\nnpm install webnative\nnpm install webnative-elm\n```\n\nThen import the javascript portion of this library and elm-taskport.\nWe'll need to initialise both of these.\n\n```js\nimport * as TaskPort from \"elm-taskport\"\nimport * as WebnativeElm from \"webnative-elm\"\n\nTaskPort.install()\nWebnativeElm.init({ TaskPort })\n\n// elmApp = Elm.Main.init()\n```\n\nOnce we have that setup, we can write our Webnative Elm code. The following is an entire Webnative app which creates or links a user account, manages user sessions and their file system, and writes to and reads from that file system.\n\n```elm\nimport Task\nimport Webnative\nimport Webnative.Auth\nimport Webnative.Configuration\nimport Webnative.Error exposing (Error)\nimport Webnative.FileSystem exposing (Base(..), FileSystem)\nimport Webnative.Namespace\nimport Webnative.Path as Path\nimport Webnative.Program exposing (Program)\nimport Webnative.Session exposing (Session)\n\n\n-- INIT\n\n\nappInfo : Webnative.AppInfo\nappInfo =\n  { creator = \"Webnative\", name = \"Example\" }\n\n\nconfig : Webnative.Configuration\nconfig =\n  appInfo\n    |\u003e Webnative.Namespace.fromAppInfo\n    |\u003e Webnative.Configuration.fromNamespace\n\n\ntype Model\n  = Unprepared\n  | NotAuthenticated Program\n  | Authenticated Program Session FileSystem\n\n\ninit : (Model, Cmd Msg)\ninit =\n  ( Unprepared\n  , -- 🚀\n    config\n      |\u003e Webnative.program\n      |\u003e Webnative.attemptTask\n          { ok = Liftoff\n          , err = HandleWebnativeError\n          }\n  )\n\n\n\n-- UPDATE\n\n\ntype Msg\n  = HandleWebnativeError Error\n  | GotFileContents String\n  | GotSession Session\n  | Liftoff Foundation\n  | RegisterUser { success : Bool }\n\n\nupdate : Msg -\u003e Model -\u003e (Model, Cmd Msg)\nupdate msg model =\n  case msg of\n    -----------------------------------------\n    -- 🚀\n    -----------------------------------------\n    Liftoff foundation -\u003e\n      let\n        newModel =\n          -- Previous authenticated session?\n          -- Presence of a FileSystem depends on your configuration.\n          case (foundation.fileSystem, foundation.session) of\n            (Just fs, Just session) -\u003e Authenticated program session fs\n            _                       -\u003e NotAuthenticated program\n      in\n      ( newModel\n\n      -- Next action\n      --------------\n      , case newModel of\n          NotAuthenticated program -\u003e\n            -- Option (A), register a new account.\n            -- We're skipping the username validation and\n            -- username availability checking here to keep it short.\n            { email = Nothing\n            , username = Just \"user\"\n            }\n            |\u003e Webnative.Auth.register program\n            |\u003e Webnative.attemptTask\n                { ok = RegisterUser\n                , error = HandleWebnativeError\n                }\n\n            -- Option (B), link an existing account.\n            -- See 'Linking' section below.\n          \n          _ -\u003e\n            Cmd.none\n      )\n\n    -----------------------------------------\n    -- 🙋\n    -----------------------------------------\n    RegisterUser { success } -\u003e\n      if success then\n        ( model\n        , program\n            |\u003e Webnative.Auth.sessionWithFileSystem\n            |\u003e Webnative.attemptTask\n                { ok = RegisterUser\n                , error = HandleWebnativeError\n                }\n        )\n      else\n        -- Could show message in create-account form.\n        (model, Cmd.none)\n\n    GotSessionAndFileSystem (Just { fileSystem, session }) -\u003e\n      ( -- Authenticated\n        case model of\n          NotAuthenticated program  -\u003e Authenticated program session fileSystem\n          _                         -\u003e model\n\n      -- Next action\n      --------------\n      , let\n          path =\n            Path.file [ \"Sub Directory\", \"hello.txt\" ]\n        in\n        \"👋\"\n            |\u003e Webnative.FileSystem.writeUtf8 fileSystem Private path\n            |\u003e Task.andThen (\\_ -\u003e Webnative.FileSystem.publish fileSystem)\n            |\u003e Task.andThen (\\_ -\u003e Webnative.FileSystem.readUtf8 fileSystem Private path)\n            |\u003e Webnative.attemptTask\n                { ok = GotFileContents\n                , error = HandleWebnativeError\n                }\n      )\n\n    -----------------------------------------\n    -- 💾\n    -----------------------------------------\n    GotFileContents string -\u003e ...\n\n    -----------------------------------------\n    -- 🥵\n    -----------------------------------------\n    HandleWebnativeError UnsupportedBrowser -\u003e        -- No indexedDB? Depends on how Webnative is configured.\n    HandleWebnativeError InsecureContext -\u003e           -- Webnative requires a secure context\n    HandleWebnativeError (JavascriptError string) -\u003e  -- Notification.push (\"Got JS error: \" ++ string)\n```\n\n\n\n# Linking\n\nWhen a user has already registered an account, they can link a device instead.\n\n```elm\n-- TODO: Yet to be implemented\n```\n\n\n\n# Filesystem\n\nAlternatively you can load the filesystem separately.  \nYou may want to do this when working with a web worker.\n\n```elm\nimport Webnative\n\nconfig =\n  { namespace = ...\n  \n  --\n  , debug = Nothing\n  , fileSystem = Just { loadImmediately = Just True, version = Nothing }\n  , permissions = Nothing\n  }\n\nWebnative.program config\n```\n\nAnd then load it either in Elm or in javascript.\n\n```elm\nWebnative.FileSystem.load program { username = \"username\" }\n```\n\n```js\nconst fs = await program.loadFileSystem(\"username\")\nwebnativeElm.init({ fileSystems: [ fs ] })\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fwebnative-elm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffission-codes%2Fwebnative-elm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fwebnative-elm/lists"}