Skip to content
SwiftMatesPublic

About

Lightweight type-safe SwiftUI NavigationStack helper. Macros for destinations & origins, deep linking, programmatic navigation. Pure Swift 6, iOS 16+, no architecture lock-in.

Topics

Resources

Stars

10 stars

Watchers

1 watching

Forks

Repository files navigation

Navi_package_logo_cropped

Main Swift Version Compatibility Platform Compatibility SPM MIT

Type-safe SwiftUI navigation built on NavigationStack.

Navi is a lightweight navigation layer for SwiftUI. It adds programmatic routing, deep linking, pop-to-destination, and destination macros to Apple’s NavigationStack — without imposing an application architecture. Pure Swift 6, iOS 16+, zero external dependencies.


What is Navi?

Navi is a type-safe navigation library for SwiftUI that builds on NavigationStack. It gives you compile-time safe routes, a clean programmatic API, multi-step deep linking, and pop-to-destination, while staying fully compatible with the native navigation model.

It does not replace NavigationStack. It is a thin typed layer on top of it.

Who is it for?
Developers who want structured, type-safe routes without adopting coordinators, TCA, or a large routing framework. It fits both small projects needing lightweight structure and large, modular codebases wanting a modern NavigationStack-native alternative to legacy coordinators.


Why Navi instead of raw NavigationStack?

Need Native NavigationStack Navi
Type-safe routes Easy to lose with NavigationPath Enum + macro, compile-time checked
Programmatic navigation Pass bindings or mutate path manually push(to:) / pop()
Deep linking Manual path construction deepLink(to:)
Pop to a specific screen Manual path surgery @OriginKey + pop(to:)

Quick Start

1. Create a controller

iOS 17+ / macOS 14+ (@Observable):

@Observable
final class DemoController: NaviController {
    var properties = NaviControllerProperties()
}

iOS 16 / macOS 13 (ObservableObject):

@MainActor
final class DemoController: NaviController, ObservableObject {
    @Published var properties = NaviControllerProperties()
}

2. Attach to NavigationStack

@main
struct BasicApp: App {
    @State private var controller = DemoController()

    var body: some Scene {
        WindowGroup {
            NavigationStack(path: $controller.properties.path) {
                HomeView()
            }
        }
    }
}

3. Define destinations

@DestinationRepresentable
enum HomeDestinations {
    case settings
    case profile
}

4. Register and navigate

struct HomeView: View {
    var body: some View {
        content
            .navigationDestination(
                for: HomeDestinations.self,
                destination: destinationView
            )
    }

    @ViewBuilder
    private func destinationView(for destination: HomeDestinations) -> some View {
        switch destination {
        case .settings: SettingsView()
        case .profile: ProfileView()
        }
    }
}

// Navigate
controller.push(to: HomeDestinations.settings)
controller.pop()

Deep linking

controller.deepLink(to: [
    HomeDestinations.settings,
    SettingsDestinations.notifications,
    NotificationsDestinations.emailNotifications
])

Pop to a destination

@DestinationRepresentable
enum HomeDestinations {
    @OriginKey case settings
    case profile
}

controller.pop(to: HomeDestinations.Origins.settings)

Examples

Example Platform Status
Examples/Basic iOS 17+ / macOS 14+ ✅
Examples/Basic-iOS16 iOS 16 / macOS 13 ✅
Examples/Coordinators iOS 16 / macOS 13 ✅

Requirements

Platform Minimum
iOS 16.0+
macOS 13.0+
Swift 6.0+ (tools 6.3)
Xcode 16.0+
  • iOS 17+ / macOS 14+ → prefer @Observable (Examples/Basic)
  • iOS 16 / macOS 13 → use ObservableObject (Examples/Basic-iOS16)

Installation

Xcode: File → Add Packages… → https://github.com/SwiftMates/Navi

Package.swift:

dependencies: [
    .package(url: "https://github.com/SwiftMates/Navi.git", from: "1.0.0")
]

FAQ

What is Navi?
A type-safe navigation layer for SwiftUI built on NavigationStack. It adds programmatic navigation, deep linking, and pop-to-destination without architecture lock-in.

Does Navi replace NavigationStack?
No. It works with NavigationStack.

Is Navi a SwiftUI router?
Yes — a lightweight, type-safe one. NavigationStack remains the underlying container.

Does it require a specific architecture?
No. Works with MVVM, TCA, coordinators, or none.

Does it support deep linking and programmatic navigation?
Yes. Use deepLink(to:), push(to:), pop(), and pop(to:).

How do I pop to a specific screen?
Mark the destination with @OriginKey, then call controller.pop(to: Destination.Origins.yourCase).

Does it support iOS 16 and Swift 6?
Yes. iOS 16+ / macOS 13+, designed for Swift 6.


Contributing

Contributions are welcome.

  1. Fork the repository
  2. Create a branch from develop:
    git checkout develop
    git checkout -b feature/your-feature
  3. Make your changes
  4. Run swift test (and example builds if relevant)
  5. Open a Pull Request against develop

Show Your Support

If you find Navi helpful, please consider:

  • Giving it a ⭐ on GitHub
  • Sharing it with fellow developers
  • Contributing to its development

Agent Skills

This package includes an Agent Skill that teaches AI coding agents the correct way to use Navi.

Supported agents

The skill lives in the project-scope directory shared by most Agent Skills-compatible tools, so Cursor, Codex, Gemini CLI, OpenCode, GitHub Copilot, Amp, and Claude Code pick it up automatically:

Agent Project path
Cursor, Codex, Gemini CLI, OpenCode, GitHub Copilot, Amp, Antigravity .agents/skills/navi/
Claude Code .claude/skills/navi (symlink)

Windsurf and other tools with their own project directory can be targeted explicitly with --agent/-a when installing (see below).

Automatic discovery

When this repository is open, compatible agents detect the skill from:

.agents/skills/navi/
├── SKILL.md
└── references/
    ├── api.md
    ├── examples.md
    └── migration.md

SKILL.md stays short and is loaded when the skill activates; references/ is only read when the agent needs the full API, examples, or migration guidance.

Manual / global install

# Install globally (available in all projects)
npx skills add SwiftMates/Navi --skill navi -g

# Install only into the current project
npx skills add SwiftMates/Navi --skill navi

# Target specific agents (e.g. Windsurf, whose project directory is .windsurf/skills/)
npx skills add SwiftMates/Navi --skill navi -a windsurf

# GitHub CLI alternative (needs --allow-hidden-dirs, because .agents/ is a hidden directory)
gh skill install SwiftMates/Navi navi --allow-hidden-dirs --scope user

Install commands resolve against the default branch, so the skill has to be merged there before it can be fetched by name.

Once installed, agents will correctly use @DestinationRepresentable, @OriginKey, push/pop/deepLink, and the right controller patterns instead of falling back to raw NavigationPath.


License

MIT. See LICENSE.

Created by SwiftMates.

About

Lightweight type-safe SwiftUI NavigationStack helper. Macros for destinations & origins, deep linking, programmatic navigation. Pure Swift 6, iOS 16+, no architecture lock-in.

Topics

Resources

Stars

10 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages