Stop Rebuilding Auth, Onboarding, and Dashboards: DesignFoundationPro NerdSnipe Inc. released DesignFoundationPro, a commercial add-on to its DesignFoundation SwiftUI package that provides 29 blocks, 47 screens, 18 navigation shells, and 9 runnable composition examples for auth, onboarding, charts, and data tables. The package claims to reduce code by ~87% compared to building from scratch and includes guardrails to ensure consistent UI when used with AI coding agents. Pricing is $149 for an individual license or $449 for a team of up to five developers, with optional annual updates at $39. Part 2 of 2.This tutorial builds on Part 1 — DesignFoundation core . If you haven't added the base package and theme yet, start there. The core package gives you tokens and primitives. DesignFoundationPro adds what comes next — 29 blocks, 47 screens, 18 navigation shells, and 9 runnable composition examples across auth, onboarding, charts, data tables, and full product verticals. The docs claim ~87% fewer lines of code versus building from scratch. That's the bet. This matters even more if an AI coding agent is doing the building. Ask an agent for a CRM screen and a settings screen in the same session and, without guardrails, you'll get two different takes on spacing, two different sidebar behaviors, and a table that's native on Mac in one screen and a scroll view pretending to be a table in the other. Pro ships with that guardrail already in place — more on that in Where to go from here. Pro sits on top of Foundation and re-exports it. Import only DesignFoundationPro and you get everything from both: YourApp your models, data, routing DesignFoundationPro 29 blocks · 47 screens · 18 shells · 9 examples DesignFoundation tokens · primitives · validation · theme engine · MIT Access: Foundation is MIT and public. Pro is a commercial add-on — repo access is granted after purchase. Licenses are lifetime no subscription ; annual updates are $39/year and entirely optional. Pricing: $149 individual · $449 team up to 5 devs . Before buying, browse everything in DFPlayground — a free macOS app that lets you preview all 29 blocks, 47 screens, and 18 shells with live theming. Pro declares Foundation as its own dependency and re-exports it via @ exported import DesignFoundation . Add only the Pro package — Foundation comes with it automatically. The Pro repo URL is provided after purchase — contact nerdsnipe.inc@gmail.com mailto:nerdsnipe.inc@gmail.com or visit the Pro page https://nerdsnipe-inc.github.io/design-foundation/pro/ to get access. dependencies: .package url: "https://github.com/NerdSnipe-Inc/DesignFoundationPro", from: "1.0.0" , , targets: .target name: "YourApp", dependencies: .product name: "DesignFoundationPro", package: "DesignFoundationPro" , , One package, one import: import DesignFoundationPro gives you both layers with no separate Foundation entry needed. Pro adds DFTheme.workspace — a platform-adaptive preset tuned for data-dense product UIs. It uses tighter desktop typography and adjusted surface tokens on macOS. For most product apps, this is the right starting point. python import SwiftUI import DesignFoundationPro @main struct MyApp: App { var body: some Scene { WindowGroup { MyRootView .dfTheme .workspace } } } Still want a custom brand?Build your DFTheme from tokens as shown in Part 1 — the individual blocks auth, charts, onboarding genuinely read whatever theme is in the environment. The composition roots and shells in Step 8 are the exception: each one hard-codes .environment \.dfTheme, .workspace internally, so mounting DFCRMRootView or any other root, or DFOnboardingFlow always renders in .workspace regardless of what theme you set upstream. If you need a branded CRM/PM/Analytics root, that's a real customization, not a one-line override — check the root's source for where it applies the theme before assuming an ambient override will reach it. Every product app needs some variation of "sidebar on Mac and iPad, tabs on iPhone," and it's one of the most-rebuilt pieces of chrome in SwiftUI — split view state, collapse behavior, selection binding, all rewritten per project. Shells are layout-only, pre-solved versions of that problem. They give you navigation structure — sidebar, columns, tabs — and expose @ViewBuilder slots for your own content. No data or business logic. | Shell | Use for | |---|---| DFStandardSidebarShell | Single sidebar + detail. macOS-native split view. | DFThreeColumnShell | Source list → content → inspector. Documents, mail. | DFWorkspaceSidebarShell | Collapsible sidebar with workspace density tokens. | DFIconRailShell | Narrow icon rail. Dashboard or tool-focused apps. | DFAdaptiveShell | Tabs on iPhone, sidebar on iPad and Mac. | DFSearchSidebarShell | Sidebar with integrated search bar at top. | Each shell has its own init signature matching its structural role. The table above lists 6 of the 18 general-purpose shells; the rest follow the same pattern. There's also a 19th, vertical-specific shell — DFSocialAppShell — built for feed/explore/notifications/profile apps specifically rather than generic navigation. It's the simplest to read, with four named @ViewBuilder slots: js struct MyRootView: View { var body: some View { DFSocialAppShell { FeedView } explore: { ExploreView } notifications: { NotificationsView } profile: { ProfileView } .dfToastHost } } The sidebar shells take typed nav data alongside a selection binding and a content @ViewBuilder : DFStandardSidebarShell takes sections: DFNavSection each section holds DFNavItem , DFAdaptiveShell takes DFAdaptiveTab , DFWorkspaceSidebarShell takes DFWorkspace plus an icon rail and account switcher. The composition roots Step 8 wire all of this for you when you're building a known vertical. MountAfter that, trigger toasts from anywhere in the tree with .dfToastHost once on any root view. DFToastQueue.shared.show text: "Saved", severity: .success . Auth screens feel simple until you're deep into forgot-password states, social provider buttons, OTP resend timers, and inline validation — a week of work for something that isn't your product's differentiator. The four Pro auth blocks — DFWelcomeBlock , DFSignInBlock , DFSignUpBlock , DFOTPBlock — each take a Configuration struct with callbacks. Form validation is wired by default using DFFormState from Foundation; set usesFormValidation: false only when you own it yourself. DFSignInBlock configuration: .init title: "Sign in to Acme", subtitle: "Welcome back", socialProviders: .apple { Task { await AuthService.signInWithApple } }, .google { Task { await AuthService.signInWithGoogle } }, , onSubmit: { email, password in // onSubmit is not async — wrap async work in a Task Task { await AuthService.signIn email: email, password: password } }, onForgotPassword: { showForgotPassword }, onSignUp: { showSignUp } The block handles layout, field spacing, validation error display, and social auth button presentation across iOS, macOS, and visionOS. Desktop density is applied automatically from @Environment \.dfUseDesktopDensity . Pair DFSignUpBlock with DFOTPBlock for email verification. Each block is independent — you control navigation between them: DFOTPBlock configuration: .init title: "Check your email", subtitle: registeredEmail, // shown under the title onSubmit: { code in // onSubmit is not async — wrap async work in a Task Task { await AuthService.verify otp: code } }, onResend: { Task { await AuthService.resendOTP } } Onboarding flows are where a lot of hand-rolled apps quietly go wrong — the "what screen comes next" logic ends up spread across seven view files with their own local state, and resuming mid-flow after the app is backgrounded is an afterthought nobody tests. DFOnboardingFlow is the highest-level Pro component: a multi-step flow that covers welcome, sign-up or sign-in, OTP verification, profile setup, permission requests, plan selection, personalisation, and a success screen. It manages its own step state persisted across launches via UserDefaults and handles back navigation. You configure the whole flow via DFOnboardingConfiguration — one struct, no subclassing: DFOnboardingFlow configuration: .init appName: "Acme", welcomeTagline: "Welcome to Acme", welcomeHeadline: "The best tool for your team.", enableAppleSignIn: true, enableGoogleSignIn: true, featureHighlights: .init icon: "sparkles", title: "AI-Powered", description: "Smart suggestions across every workflow." , .init icon: "person.3", title: "Built for Teams", description: "Real-time collaboration, no friction." , , requestedPermissions: .notifications , showPlanSelection: true, planTiers: .init name: "Free", price: "$0", period: "forever", features: "3 projects", "1,000 API calls" , isPopular: false , .init name: "Pro", price: "$49", period: "/ month", features: "Unlimited projects", "Priority support" , isPopular: true, badge: "Most Popular" , , personalisationTags: .init id: "startup", label: "Startup" , .init id: "enterprise", label: "Enterprise" , .init id: "freelance", label: "Freelance" , , onSignUp: { name, email, password in // Return Bool: true = success, false = failure e.g. email taken return await AuthService.signUp name: name, email: email, password: password }, onSignIn: { email, password in return await AuthService.signIn email: email, password: password }, onOTPVerify: { code in return await AuthService.verify otp: code }, onOTPResend: { await AuthService.resendOTP }, onProfileSave: { name, avatar in await ProfileService.save name, avatar }, onPermissionRequest: { perm in await PermissionService.request perm }, onPlanSelected: { tier in BillingService.select tier }, onPersonalisationComplete: { tags in ProfileService.saveTags tags }, onComplete: { AppState.shared.isOnboarded = true } That one initialiser configures every step. If the user backgrounds the app mid-onboarding, they resume where they left off. Swift Charts gives you the primitives, but every dashboard still needs the same surrounding scaffolding — a period picker, a legend, loading and empty states, consistent theme colors per series. That's the part that gets rebuilt per project. Chart blocks are composables, not screen-locked. Drop them into your own views, not just the Analytics root. They use Swift Charts under the hood and inherit theme colors automatically. | Block | Use for | |---|---| DFLineChartBlock | Trends, time series, cumulative metrics | DFBarChartBlock | Category comparison, period-over-period | DFDonutChartBlock | Part-to-whole breakdown, proportions | DFStatCardBlock | Single metric with delta and trend sparkline | Don't useIt's a loading/skeleton state only. For loading chart data, pass DFChartPlaceholderBlock in shipping UI. isLoading: true to the real chart block instead. // Keyword arguments must appear in the same order as the initializer declares them — // isLoading: comes right after title:, before data:. DFLineChartBlock configuration: .init title: "Active Users", isLoading: isFetchingData, data: "Mon", 182 , "Tue", 195 , "Wed", 188 , "Thu", 212 , "Fri", 240 , "Sat", 198 , , periods: DFChartPeriodPreset.allCases, selectedPeriod: .sevenDays, onPeriodChange: { period in // onPeriodChange is not async — wrap async work in a Task Task { await loadTrend for: period } }, height: isDesktop ? 140 : 220 The period toolbar is built in. Your domain period enum conforms to DFChartPeriodRepresentable if you need custom ranges beyond the preset. A data table that feels native on macOS keyboard navigation, Return to activate a row and still works on a phone-width screen is two different UIs wearing the same data. Building both, and deciding which one renders where, is a recurring cross-platform tax. DFDataTable ships in Foundation but it's most useful in Pro-scale apps. On macOS it renders a native Table with keyboard navigation and Return-to-activate. On iPhone it falls back to scrollable header + rows. Use it on regular-width layouts; keep DFList with swipe actions on compact phone screens where that fits better. js @State private var selectedIDs: Set