{"id":1817,"url":"https://github.com/JensRavens/Interstellar","last_synced_at":"2025-08-02T04:32:39.867Z","repository":{"id":32210105,"uuid":"35783905","full_name":"JensRavens/Interstellar","owner":"JensRavens","description":"Simple and lightweight Functional Reactive Coding in Swift for the rest of us","archived":true,"fork":false,"pushed_at":"2019-04-23T15:48:10.000Z","size":223,"stargazers_count":1084,"open_issues_count":8,"forks_count":211,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-07-05T03:26:40.711Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/JensRavens.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":"2015-05-17T21:33:35.000Z","updated_at":"2025-06-25T20:30:14.000Z","dependencies_parsed_at":"2022-08-20T20:50:36.323Z","dependency_job_id":null,"html_url":"https://github.com/JensRavens/Interstellar","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/JensRavens/Interstellar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JensRavens%2FInterstellar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JensRavens%2FInterstellar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JensRavens%2FInterstellar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JensRavens%2FInterstellar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JensRavens","download_url":"https://codeload.github.com/JensRavens/Interstellar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JensRavens%2FInterstellar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334618,"owners_count":24233793,"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-08-02T02:00:12.353Z","response_time":74,"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-01-05T20:15:56.501Z","updated_at":"2025-08-02T04:32:39.573Z","avatar_url":"https://github.com/JensRavens.png","language":"Swift","readme":"![Interstellar](https://raw.githubusercontent.com/JensRavens/Interstellar/assets/header.jpg)\n\n[![Build Status](https://travis-ci.org/JensRavens/Interstellar.svg)](https://travis-ci.org/JensRavens/Interstellar)\n[![CocoaPods Version](https://img.shields.io/cocoapods/v/Interstellar.svg)](https://cocoapods.org/pods/Interstellar)\n[![CocoaPods Plattforms](https://img.shields.io/cocoapods/p/Interstellar.svg)](https://cocoapods.org/pods/Interstellar)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\nThe simplest `Observable\u003cT\u003e` implementation for Functional Reactive Programming you will ever find.\n\n\u003e This library does not use the term FRP (Functional Reactive Programming) in the way it was\n\u003e defined by Conal Elliot, but as a paradigm that is both functional and reactive. Read more\n\u003e about the difference at [Why I cannot say FRP but I just did](https://medium.com/@andrestaltz/why-i-cannot-say-frp-but-i-just-did-d5ffaa23973b).\n\n## Features\n\n- [x] Lightweight, simple, cross plattform FRP\n- [x] Multithreading with GCD becomes a breeze\n- [x] Most of your methods will conform to the needed syntax anyway.\n- [x] Swift 3 and 4 compatibility\n- [x] Multithreading with GCD becomes a breeze via WarpDrive\n- [x] Supports Linux and `swift build`\n- [x] BYOR™-technology (Bring Your Own `Result\u003cT\u003e`)\n\n## Requirements\n\n- iOS 7.0+ / Mac OS X 10.10+ / Ubuntu 14.10\n- Xcode 8\n\n---\n\n## Usage\n\n\u003e For a full guide on how this implementation works see the series of blog posts about\n\u003e [Functional Reactive Programming in Swift](http://jensravens.de/series/functional-reactive-programming-in-swift/)\n\u003e or the talk at UIKonf 2015 [How to use Functional Reactive Programming without Black Magic](http://jensravens.de/uikonf-talk/).\n\n### Creating and updating a signal\n\n``` swift\nlet text = Observable\u003cString\u003e()\n\ntext.subscribe { string in\n  print(\"Hello \\(string)\")\n}\n\ntext.update(\"World\")\n```\n\n### Mapping and transforming observables\n\n``` swift\nlet text = Observable\u003cString\u003e()\n\nlet greeting = text.map { subject in\n  return \"Hello \\(subject)\"\n}\n\ngreeting.subscribe { text in\n  print(text)\n}\n\ntext.update(\"World\")\n```\n\n### Use functions as transforms\n\n``` swift\nlet text = Observable\u003cString\u003e()\nlet greet: (String)-\u003eString = { subject in\n  return \"Hello \\(subject)\"\n}\ntext\n  .map(greet)\n  .subscribe { text in\n    print(text)\n  }\ntext.update(\"World\")\n```\n\n### Handle errors in sequences of functions\n\n``` swift\nlet text = Observable\u003cString\u003e()\n\nfunc greetMaybe(subject: String) throws -\u003e String {\n  if subject.characters.count % 2 == 0 {\n    return \"Hello \\(subject)\"\n  } else {\n    throw NSError(domain: \"Don't feel like greeting you.\", code: 401, userInfo: nil)\n  }\n}\n\ntext\n  .map(greetMaybe)\n  .then { text in\n    print(text)\n  }\n  .error { error in\n    print(\"There was a greeting error\")\n  }\ntext.update(\"World\")\n```\n\n### This also works for asynchronous functions\n\n``` swift\nlet text = Observable\u003cString\u003e()\nfunc greetMaybe(subject: String) -\u003e Observable\u003cResult\u003cString\u003e\u003e {\n  if subject.characters.count % 2 == 0 {\n    return Observable(.success(\"Hello \\(subject)\"))\n  } else {\n    let error = NSError(domain: \"Don't feel like greeting you.\", code: 401, userInfo: nil)\n    return Observable(.error(error))\n  }\n}\n\ntext\n  .flatMap(greetMaybe)\n  .then { text in\n    print(text)\n  }\n  .error { _ in\n    print(\"There was a greeting error\")\n  }\ntext.update(.success(\"World\"))\n```\n\n## Flatmap is also available on observables\n\n```swift\nlet baseCost = Observable\u003cInt\u003e()\n\nlet total = baseCost\n  .flatMap { base in\n    // Marks up the price\n    return Observable(base * 2)\n  }\n  .map { amount in\n    // Adds sales tax\n    return Double(amount) * 1.09\n  }\n\ntotal.subscribe { total in\n  print(\"Your total is: \\(total)\")\n}\n\nbaseCost.update(10) // prints \"Your total is: 21.8\"\nbaseCost.update(122) // prints \"Your total is: 265.96\"\n\n```\n\n---\n\n## Communication\n\n- If you **found a bug**, open an issue.\n- If you **have a feature request**, open an issue.\n- If you **want to contribute**, open an issue or submit a pull request.\n\n## Installation\n\n\u003e **Dynamic frameworks on iOS require a minimum deployment target of iOS 8 or later.**\n\u003e To use Interstellar with a project targeting iOS 7, you must include all Swift files directly in your project.\n\n### CocoaPods\n\n[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:\n\n``` bash\n$ gem install cocoapods\n```\n\nTo integrate Interstellar into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n``` ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '8.0'\nuse_frameworks!\n\npod 'Interstellar'\n```\n\nThen, run the following command:\n\n``` bash\n$ pod install\n```\n\n### swift build\n\nAdd Interstellar to your `Package.swift`:\n\n```swift\nimport PackageDescription\n\nlet package = Package(\n  name: \"Your Awesome App\",\n  targets: [],\n  dependencies: [\n    .Package(url: \"https://github.com/jensravens/interstellar.git\", majorVersion: 2),\n  ]\n)\n```\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.\n\nYou can install Carthage with [Homebrew](http://brew.sh/) using the following command:\n\n``` bash\n$ brew update\n$ brew install carthage\n```\n\nTo integrate Interstellar into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n``` ogdl\ngithub \"JensRavens/Interstellar\"\n```\n\n---\n\n## FAQ\n\n### Why use Interstellar instead of [insert your favorite FRP framework here]?\n\nInterstellar is meant to be lightweight. There are no UIKit bindings, no heavy constructs - just a simple `Observable\u003cT\u003e`. Therefore it's easy to understand and portable (there is no dependency except Foundation).\n\nAlso Interstellar is supporting BYOR (bring your own `Result\u003cT\u003e`). Due to its protocol based implementation you can use result types from other frameworks directly with Interstellar methods.\n\n* * *\n\n## Credits\n\nInterstellar is owned and maintained by [Jens Ravens](http://jensravens.de).\n\n## Changelog\n\n- *1.1* added compability with Swift 2. Also renamed bind to flatMap to be consistent with `Optional` and `Array`.\n- *1.2* `Thread` was moved to a new project called [WarpDrive](https://github.com/jensravens/warpdrive)\n- *1.3* WarpDrive has been merged into Interstellar. Also Interstellar is now divided into subspecs via cocoapods to make it easy to just select the needed components. The basic signal library is now \"Interstellar/Core\".\n- *1.4* Support `swift build` and the new Swift package manager, including support for Linux. Also removed deprecated bind methods.\n- *2* Introducing `Observable\u003cT\u003e`, the successor of Signal. Use the `observable` property on signals to migrate your code from `Signal\u003cT\u003e`. Also adding Linux support for Warpdrive and introduce BYOR™-technology (Bring Your Own `Result\u003cT\u003e`).\n- *2.1* Update to Swift 3.2 to make it compatible with Swift 4.\n- 2.2 Update to Swift 4.1, fixing build warnings on Xcode 9.3 (Maintains backwards compatibility with Swift 3.3 projects).\n\n## License\n\nInterstellar is released under the MIT license. See LICENSE for details.\n","funding_links":[],"categories":["Libraries","Swift","Reactive Programming","Frameworks"],"sub_categories":["[Swift](https://developer.apple.com/swift)","Other free courses","Prototyping","Other Parsing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJensRavens%2FInterstellar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJensRavens%2FInterstellar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJensRavens%2FInterstellar/lists"}