{"id":15633931,"url":"https://github.com/guidomb/portal","last_synced_at":"2025-04-30T06:42:02.371Z","repository":{"id":70706416,"uuid":"88569506","full_name":"guidomb/Portal","owner":"guidomb","description":"A (potentially) cross-platform, unidirectional data flow framework to build applications using a declarative and immutable UI API.","archived":false,"fork":false,"pushed_at":"2019-02-05T03:02:29.000Z","size":694,"stargazers_count":50,"open_issues_count":2,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-18T21:31:33.832Z","etag":null,"topics":["architecture","declarative-ui","framework","functional-programming","immutable","ios","state-management","swift","ui"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/guidomb.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":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-18T01:54:31.000Z","updated_at":"2024-01-03T15:29:55.000Z","dependencies_parsed_at":"2023-02-28T23:30:50.434Z","dependency_job_id":null,"html_url":"https://github.com/guidomb/Portal","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guidomb%2FPortal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guidomb%2FPortal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guidomb%2FPortal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guidomb%2FPortal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guidomb","download_url":"https://codeload.github.com/guidomb/Portal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251658132,"owners_count":21622817,"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":["architecture","declarative-ui","framework","functional-programming","immutable","ios","state-management","swift","ui"],"created_at":"2024-10-03T10:50:40.174Z","updated_at":"2025-04-30T06:42:02.322Z","avatar_url":"https://github.com/guidomb.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"Portal\n======\n\n[![Build Status](https://www.bitrise.io/app/35802d5e71a76792/status.svg?token=Lk2FPQhMq_PaxQDKN47dRA\u0026branch=master)](https://www.bitrise.io/app/35802d5e71a76792)\n[![Swift](https://img.shields.io/badge/swift-4-orange.svg?style=flat)](#)\n[![GitHub release](https://img.shields.io/github/release/guidomb/Portal.svg)]()\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Platform](https://img.shields.io/badge/platform-iOS-lightgrey.svg?style=flat)](#)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT)\n\nA (potentially) cross-platform, unidirectional data flow framework to build applications using a declarative and immutable UI API.\n\n**WARNING!: This is still a work-in-progress, although the minimum features are available to create real world applications the API is still under design and some key optimizations are still missing. Use at your own risk.**\n\n## TL; DR;\n\n * An application framework heavily inspired by the [Elm architecture](https://guide.elm-lang.org/architecture/).\n * Declarative API inspired by Elm and React.\n * 100% in Swift and decoupled from UIKit which makes it (potentially) cross-platform.\n * Uses facebook's [Yoga](https://github.com/facebook/yoga). A cross-platform layout engine that implements Flexbox which is used by ReactNative.\n * Leverage the Swift compiler in order to have a strongly type-safe API.\n\n\n\nAll you need to do to have a working application is to implement the `Application` protocol.\n\n```swift\npublic protocol Application {\n\n    associatedtype MessageType\n    associatedtype StateType\n    associatedtype CommandType\n    associatedtype RouteType: Route\n    associatedtype SubscriptionType: Equatable\n    associatedtype NavigatorType: Equatable\n\n    var initialState: StateType { get }\n\n    var initialRoute: RouteType { get }\n\n    func translateRouteChange(from currentRoute: RouteType, to nextRoute: RouteType) -\u003e MessageType?\n\n    func update(state: StateType, message: MessageType) -\u003e (StateType, CommandType?)?\n\n    func view(for state: StateType) -\u003e View\u003cRouteType, MessageType, NavigatorType\u003e\n\n    func subscriptions(for state: StateType) -\u003e [Subscription\u003cMessageType, RouteType, SubscriptionType\u003e]\n\n}\n```\n\nThe application state is updated in a centralized place every time a new message arrives. Messages can be triggered by user actions or as the result of a computation or access to an external system (like a web service o database).\n\nEvery time a new messages arrives, the `update` function is called. This function responsibility is to provide the next application's state and return a command to be executed in case side-effects are needed, like fetching data from a web service.\n\nOnce a new state has been computed the `view` function will be called to render a new view.\n\nHere is a sneak peak of the API but you can also check [this examples](https://github.com/guidomb/Portal#example) or read the library [documentation](./Documentation/View.md) to learn more about the main concepts.\n\n```swift\nenum Message {\n\n  case like\n  case goToDetailScreen\n\n}\n\nlet component: Component\u003cMessage\u003e = container(\n  children: [\n    label(\n      text: \"Hello Portal!\",\n      style: labelStyleSheet() { base, label in\n          base.backgroundColor = .white\n          label.textColor = .red\n          label.textSize = 12\n      },\n      layout: layout() {\n          $0.flex = flex() {\n              $0.grow = .one\n          }\n          $0.justifyContent = .flexEnd\n      }\n    )\n    button(\n      properties: properties() {\n          $0.text = \"Tap to like!\"\n          $0.onTap = .like\n      }\n    )\n    button(\n      properties: properties() {\n          $0.text = \"Tap to got to detail screen\"\n          $0.onTap = .goToDetailScreen\n      }\n    )\n  ]\n)\n```\n\n## Installation\n\n### Carthage\n\nInstall [Carthage](https://github.com/Carthage/Carthage) first by either using the [official .pkg installer](https://github.com/Carthage/Carthage/releases) for the latest release or If you use [Homebrew](http://brew.sh) execute the following commands:\n\n```\nbrew update\nbrew install carthage\n```\n\nOnce Carthage is installed add the following entry to your `Cartfile`\n\n```\ngithub \"guidomb/Portal\" \"master\"\n```\n\n### Manual\n\nTODO\n\n## Example\n\nFor some examples on how the API looks like and how to use this library check\n\n * The [example](./Example) target in this repository.\n * The [Voices](https://github.com/guidomb/voices) Twitter client application.\n\n## Documentation\n\nPortal is still a work-in-progress. Documentation will be added as the library matures inside the [Documentation](./Documentation) directory.\nYou can read the library [overview](./Documentation/Overview.md) to learn more about the main concepts.\n\n## Contribute\n\n### Setup\n\nInstall [Carthage](https://github.com/Carthage/Carthage) first, then run\n\n```\ngit clone git@github.com:guidomb/Portal.git\ncd Portal\nscript/bootstrap\nopen Portal.xcodeproj\n```\n\nIf you want to know how the project is doing, what features are in the pipeline for the next milestone and whare are the ideas that already in the backlog, check [this repo's project](https://github.com/guidomb/Portal/projects/1)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguidomb%2Fportal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguidomb%2Fportal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguidomb%2Fportal/lists"}