SwiftHub: a GitHub iOS client built as a clean architecture reference
GitHub iOS client in RxSwift and MVVM-C clean architecture
At a glance
- What is it?
- khoren93/SwiftHub is an MIT licensed iOS client for GitHub written in Swift with RxSwift and MVVM-C. It splits the API between REST v3 and GraphQL v4 depending on the authentication mode, and its own feature list still carries unchecked items such as tests and SwiftUI.
- Who is it for?
- Adopt SwiftHub if you want a readable, complete iOS client for GitHub to study, to fork, or to use as a starting point for a clean architecture app, and you can live with the dependency list it carries, from Moya and Apollo through Firebase and AdMob.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A client that doubles as an architecture sample
SwiftHub is a GitHub client for iOS, and the description puts the point of view first: a client in RxSwift and MVVM-C clean architecture. The feature list is long, covering trending repositories and users, advanced search and sorting with language filters, repository and user details, issues, commits, pull requests, contributors, issue and pull request message threads, line counting, star history graphs, file history browsing, profile visualisation and a 3D model of the contribution graph.
What makes it worth reading is not the feature count but the shape of the code. The technologies section lists clean architecture with RxSwift and MVVM, flow coordinators for navigation, programmatic UI with SnapKit, Hero for custom transition animations, and a mix of third party libraries for the rest. Screenshots cover the trending repository, search, repository details, user search, user details and settings screens, and a mind map document describes the module structure in full.
The audience splits in two. One group wants a working GitHub app on a phone. The other, larger group wants a reference implementation of clean architecture in a real app with real network boundaries, since most architecture samples are small enough to avoid the hard parts. SwiftHub is closer to the second, and it is explicitly a demo of how to structure an iOS application rather than a product with a service behind it.
One piece of scope is deliberately left out. Cloning a repository directly into the app is marked as not done, and the linked SwiftGit2 project is the intended route for that capability.
Two API surfaces chosen by authentication mode
The most instructive design decision in the project is that it talks to two different GitHub APIs, and the choice is tied to how the user authenticates rather than to taste.
For unauthenticated or basic authentication, the app uses the REST API v3, with Moya as the networking layer and ObjectMapper for decoding. For OAuth2 authentication it switches to the GraphQL API v4 through Apollo. Both of those are listed under the technologies section with links to their projects.
The reason this split is defensible is that the two APIs answer different questions well. REST v3 is a complete, stable, per-resource interface, and it works for a client that only needs to fetch a user, a repository or a list of issues. GraphQL v4 lets one request ask for exactly the fields a screen needs, which matters for a mobile client that renders dense detail pages and would otherwise download more than it shows. The cost of the GraphQL route is a generated client, a typed query layer and a schema to keep in step with, and the cost of the REST route is over-fetching and client side assembly of nested data.
Three authentication modes are supported, and the README lists them as checked: basic, personal access token and OAuth2. Which one you pick determines which API layer the app talks through, so an adopter has to decide this before anything else, not after the models are written.
Building it starts with Xcode and the Ruby toolchain
The build and run section of the README is short and concrete. You need Xcode from the App Store, and if the command line tools are not installed yet, the README asks you to run this first:
xcode-select --installThat command installs Xcode's command line tools on the machine. After that comes Bundler, which the project uses to manage its Ruby gem dependencies:
[sudo] gem install bundlerThe square brackets around sudo are in the original, so the command is presented as a choice depending on whether your gem installation needs elevation. The Ruby dependency management is not incidental: the project drives iOS release automation with Fastlane, and the repository carries a Gemfile and a checked in Gemfile.lock next to the Podfile and Podfile.lock for the CocoaPods side.
The iOS dependencies themselves are declared in the Podfile, with a lockfile committed alongside, and the workspace is SwiftHub.xcworkspace, with SwiftHub.xcodeproj/ also present. Opening the workspace rather than the project is the normal CocoaPods workflow, and the lockfiles in the repository mean a clean checkout resolves to the versions the author tested with rather than to whatever is current.
The remaining toolchain in the repository is a mix of code quality and inspection aids: SwiftLint with a .swiftlint.yml configuration, Jazzy with a .jazzy.yaml for documentation generation, a Postman directory holding a collection for testing the web services, a Sketch directory with the design files, and an iThoughtsX directory holding the mind map source. That last set is a reminder that a project of this shape carries design and documentation artefacts alongside the code, and they are in the repository rather than in a separate design tool.
The feature list still has empty boxes, and they are the interesting ones
The README uses checkboxes, and the unchecked ones describe what the project is not. The list of technologies that are not yet in place covers migrating to Apple's SwiftUI and Combine, adding dependency injection with Swinject, and adding tests. The feature list has one unchecked item too, cloning a repository directly into the app.
Two of those gaps deserve scrutiny. The dependency injection slot is empty while the architecture is clean architecture and MVVM-C, and those two usually travel together, so the object graph in this sample is wired by hand. That is a deliberate trade-off for a sample project, since a hand wired graph is easier to follow, but it means the code is not a template for a large team where the wiring would have to change under pressure.
The tests gap is more interesting, because the repository does contain SwiftHubTests/ and SwiftHubUITests/ directories while the README still lists adding tests as pending. The two statements are not in conflict, but they do not fully agree either, and the honest reading is that test coverage exists somewhere below the level the documentation claims. Anyone planning to rely on this code in production needs to look at those two directories directly rather than at the checkbox.
The SwiftUI and Combine migration gap is the one that will age fastest. The app is built with UIKit, SnapKit and RxSwift, and a migration to the current Apple frameworks is listed as future work with no indication of when it might happen. A pattern that is well known to work is still a pattern, and this is a case where the sample teaches a style that is no longer the default.
Analytics, crash reporting and ads travel with the app
The technologies list includes several services that are not part of the architecture demonstration but are part of what you inherit. Mixpanel and Firebase analytics events are wired through the Umbrella library, crash reporting goes to Crashlytics, and there is a Google ads implementation through Firebase AdMob that can be enabled or disabled from the settings screen.
The ads toggle is a good sign, because an in-app switch means the project is aware that shipping ads is a choice rather than a default. It also means the code paths exist regardless of the setting, which is something to consider if you fork this into a product of your own.
There are two other dependencies with similar weight. The app supports in-app language switching across English, Chinese, Russian and Armenian using Localize-Swift, and it shows a WhatsNew section through WhatsNewKit, which is the standard pattern for presenting release notes inside the app. Both are reasonable choices, and both are choices you inherit rather than design.
The repository also carries a PRIVACY_POLICY.md alongside the MIT LICENSE, and that pairing is the one to read closely. An MIT licence covers the source code, and it says nothing about the data practices of an app that reports analytics events, reports crashes and serves advertising. Anyone building a product from this code needs to reconcile the two documents for their own distribution, which is a legal review rather than a technical decision, but the fact that a privacy policy file sits in the repository confirms that the author treated it as a real requirement.
Recent commits, old release tags
The repository is not archived, and the last push was on 2026-10-17. That is the current state of the code, and it is the fact to rely on when judging whether the project is being worked on.
The tagged releases tell a different story. The newest tag is v1.10.0, released on 2021-10-13, and its name describes its content as RxSwift 6.x support. Before that came v1.9.9 in April 2021 and v1.9.8 in May 2020, with descriptive names of their own. So the release history stops roughly five years before the last commit, while the working tree keeps moving.
The gap between the two signals is the interesting part. A repository that is still receiving commits but has not cut a release since 2021 is usually one where work continues on the default branch without a shipping rhythm, and the version numbering says the same thing: the last three tags are all 1.9.x and 1.10.0, which is the numbering of an application that reached a stable point and then stopped versioning formally.
For an adopter, the practical read is that the code is worth reading and the release artefacts are not a versioning story to plan around. The README points to a sibling project, FlutterHub, described as the Flutter version available at an early stage, and the pair suggests how the author iterates: a reference client in one stack, with a port in another.
MIT licensing applies to the code, with the LICENSE file in the repository root. The same caution applies as with any MIT project that ships third party services: the licence covers this source, not the behaviour of the analytics and advertising SDKs it pulls in.
The Flutter sibling and the official client are the real alternatives
Two comparisons are worth making, and they answer different questions.
The first alternative is the author's own FlutterHub, linked from the README as the Flutter version available at an early stage. The difference in approach is the stack, not the product. SwiftHub is Swift, UIKit, RxSwift and MVVM-C with CocoaPods and a Ruby Fastlane toolchain, so it needs a Mac with Xcode to build. A Flutter client needs the Flutter SDK and produces a codebase that targets several mobile platforms from one source, at the cost of a larger framework footprint and a rendering model that is not the platform's own. The description of the Flutter version as being at an early stage tells you which one is more complete, and the sibling link also signals that the architecture ideas transfer between them.
The second comparison is with the official GitHub client, and here the difference is architectural rather than stylistic. A first party client can rely on undocumented behaviour, on internal endpoints and on a close relationship with the API's development. This project uses the public REST v3 and GraphQL v4 surfaces, keeps its credentials handling in the open, and adds a layer of third party services that a first party app would not need. That is a real constraint, and it is the reason a third party client usually lags behind on the newest features.
The trade for a developer reading this code is the trade this kind of project always makes. You get a complete, inspectable application whose boundaries are visible, and in exchange you get the public API surface and the maintenance rhythm of a volunteer project whose last tagged release is v1.10.0 from 2021-10-13.
Editorial conclusion
Adopt SwiftHub if you want a readable, complete iOS client for GitHub to study, to fork, or to use as a starting point for a clean architecture app, and you can live with the dependency list it carries, from Moya and Apollo through Firebase and AdMob. Do not adopt it as a maintained template for production work without checking the gaps the README still lists, namely tests, dependency injection and the SwiftUI migration, and do not treat the tagged releases as a support signal, since the newest tag is v1.10.0 from 2021-10-13. Before you build, install Xcode and run xcode-select --install, install Bundler with [sudo] gem install bundler, and read the Podfile and PRIVACY_POLICY.md, since the analytics and advertising dependencies determine what you inherit.
Frequently asked questions
How do I build and run SwiftHub locally?
Install Xcode from the App Store, run xcode-select --install for the command line tools, and install Bundler with [sudo] gem install bundler for the Ruby gem dependencies. The iOS dependencies are declared in the Podfile, and the project is opened through SwiftHub.xcworkspace.
Which GitHub APIs and authentication modes does SwiftHub use?
It supports basic, personal access token and OAuth2 authentication. Unauthenticated or basic access goes through the REST API v3 with Moya and ObjectMapper, while OAuth2 uses the GraphQL API v4 through Apollo.
Does SwiftHub have unit and UI tests?
The README still lists adding tests as an open item, while the repository contains SwiftHubTests/ and SwiftHubUITests/ directories. Check those directories directly to judge the coverage you inherit.
What is the licence and release history of SwiftHub?
The project is MIT licensed with a LICENSE file in the repository root, and it also ships a PRIVACY_POLICY.md covering the analytics, crash reporting and advertising services it integrates. The newest tagged release is v1.10.0 from 2021-10-13, while the last push was on 2026-10-17.
Does SwiftHub support dark mode and multiple languages?
Yes, colour themes in light and dark modes are listed as supported through RxTheme, and in-app language switching covers English, Chinese, Russian and Armenian through Localize-Swift. The Google ads implementation can also be enabled or disabled from the settings screen.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/khoren93-swifthub)Was this useful?