Programming language: Swift
License: MIT License
Tags: App Routing    
Latest version: v3.2.0

Crossroad alternatives and similar libraries

Based on the "App Routing" category.
Alternatively, view Crossroad alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Crossroad or a related project?

Add another 'App Routing' Library



Build Status Language Carthage compatible CocoaPods Compatible Platform License

Route URL schemes easily.

Crossroad is an URL router focused on handling Custom URL Scheme. Using this, you can route multiple URL schemes and fetch arguments and parameters easily.

This library is developed in working time for Cookpad.




pod 'Crossroad'


github "giginet/Crossroad"

Basic Usage

You can use DefaultRouter to define route definitions.

Imagine to implement Pokédex on iOS. You can access somewhere via URL scheme.

router = DefaultRouter(scheme: "pokedex")
    ("/pokemons", { context in 
        let type: Type? = context[parameter: "type"]
        presentPokedexListViewController(for: type)
        return true 
    ("/pokemons/:pokedexID", { context in 
        guard let pokedexID: Int? = context[argument: "pokedexID"] else {
            // pokedexID must be Int
            return false
        if !Pokedex.isExist(pokedexID) { // Find the Pokémon by ID
            return false
        presentPokedexDetailViewController(of: pokedexID)
        return true 
    // ...

let canRespond25 = router.responds(to: URL(string: "pokedex://pokemons/25")!) // Pikachu(No. 25) is exist! so it returns true
let canRespond9999 = router.responds(to: URL(string: "pokedex://pokemons/9999")!) // No. 9999 is unknown. so it returns false
router.openIfPossible(URL(string: "pokedex://pokemons/25")!) // Open Pikachu page
router.openIfPossible(URL(string: "pokedex://pokemons?type=fire")!) // Open list of fire Pokémons page

~ iOS 12

You can also skip schemes on URLs. URLPattern /search/:keyword means pokedex://search/:keyword on the router.

In common use case, you should call router.openIfPossible on UIApplicationDelegate method.

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
    return router.openIfPossible(url, options: options)

iOS 13+

Or, if you are using SceneDelegate with a modern app:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let context = URLContexts.first else {
    router.openIfPossible(context.url, options: context.options)

Argument and Parameter

: prefixed components on passed URL pattern mean argument.

For example, if passed URL matches pokedex://search/:keyword, you can get keyword from Context.

// matches: pokedex://search/Pikachu
let keyword: String = context[argument: "keyword"] // Pikachu

And more, you can get query parameters if exist.

// matches: pokedex://search/Pikachu?generation=1
let generation: Int? = context[parameter: "generation"] // 1

Currently supported type is Int, Int64, Float, Double, Bool, String and URL.

Enum argument

You can use enum as arguments by implementing Parsable.

enum Type: String, Parsable {
    case normal
    case fire
    case water
    case grass
    // ....

// matches: pokedex://pokemons?type=fire
let type: Type? = context[parameter: "type"] // .fire

Comma-separated list

You can treat comma-separated query strings as Array.

// matches: pokedex://pokemons?types=water,grass
let types: [Type]? = context[parameter: "types"] // [.water, .grass]

Custom argument

You can also define own arguments by implementing Parsable. This is an example to parse custom struct.

struct User {
    let name: String
extension User: Parsable {
    init?(from string: String) {
        self.name = string

Custom Router

You can add any payload to Router.

struct UserInfo {
    let userID: Int64
let router = Router<UserInfo>(scheme: "pokedex")
    ("pokedex://pokemons", { context in 
        let userInfo: UserInfo = context.userInfo
        let userID = userInfo.userID
        return true
    // ...
let userInfo = UserInfo(userID: User.current.id)
router.openIfPossible(url, userInfo: userInfo)

Universal Links

You can make routers handle with Universal Links.

Of course, you can also use Firebase Dynamic Link or other similar services.

let router = DefaultRouter(url: URL(string: "https://my-awesome-pokedex.com")!)

Parse URL patterns

If you maintain a complex application and you want to use independent URL pattern parsers without Router. You can use URLParser.

let parser = URLParser<Void>()
let context = parser.parse(URL(string: "pokedex:/pokemons/25")!, 
                           in: "pokedex://pokemons/:id")

Supported version

Latest version of Crossroad requires Swift 5.0 or above.

Use 1.x instead on Swift 4.1 or lower.

Crossroad Version Swift Version Xcode Version
3.x 5.0 Xcode 10.3
2.x 5.0 Xcode 10.2
1.x 4.0 ~ 4.2 ~ Xcode 10.1


Crossroad is released under the MIT License.

Header logo is released under the CC BY 4.0 license. Original design by @Arslanshn.

*Note that all licence references and agreements mentioned in the Crossroad README section above are relevant to that project's source code only.