Thanks for your interest in contributing! Here's how to get started.
- Fork the repo
- Clone your fork
git clone https://github.com/YOUR_USERNAME/verceltics.git
- Open
ios/verceltics.xcodeprojin Xcode for the app, or runcd web && npm cifor the website - Create a branch
git checkout -b feature/your-feature
- Make your changes
- Build and test on iOS 18.0+, run
./scripts/test.sh, and runcd web && npm run buildfor website changes - Commit and push
- Open a Pull Request
- SwiftUI only — No UIKit wrappers unless absolutely necessary
- No new third-party dependencies without discussion — RevenueCat is already used for App Store entitlements; keep everything else lean
- All appearances — Every screen must work in System, Light, and Dark appearance. Use
AppTheme; do not hardcode a one-mode palette. - iOS 18.0+ — Minimum deployment target
- Swift concurrency — The project uses Swift 5 language mode with
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor. Mark pure data models and helpersnonisolated; useasync/await, actors, and@Observable. - iPad-aware — Avoid arbitrary fixed content widths; respect
@Environment(\.horizontalSizeClass), sharedAppLayoutlimits, and adaptive grids - Provider boundaries — Credentials must stay in the device-only Keychain and travel only to the selected provider's allowed HTTPS hosts. Preserve redirect blocking and confirmation for detected writes, purchases, and destructive requests.
- Catalog integrity — Update generated provider operation catalogs through the scripts in
scripts/; do not hand-edit generated JSON without updating its source and tests. - Keep it minimal — Don't add features nobody asked for
ios/verceltics/Components/ProviderVisuals.swift is the canonical design system. Build with the shared primitives rather than recreating card chrome locally:
- Canvas and surfaces:
AppTheme.canvas,surface, andsurfaceRaisedadapt across Light and Dark appearance. - Text and state: use
textPrimary,textSecondary,textTertiary,signal,success,warning, anddanger. - Cards: prefer
.appSurface()for neutral surfaces and.providerSurface(accent:)when provider identity matters. - Radii:
AppTheme.panelRadius(16),controlRadius(13), andiconRadius(10), always with continuous corners. - Provider color: reserve it for identity, a thin accent rail, an icon tile, or status—not decorative page gradients.
- Press feedback: wrap interactive surfaces in
Buttonand apply.buttonStyle(PressScaleButtonStyle()). - Hit testing: HStacks with
Spacer()need.contentShape(Rectangle())so the gap is tappable.
- Use SF Symbols for icons (heavy / bold weights for accent dots)
- Use
.system(size:weight:)fonts with explicit sizes; rounded design + monospaced digits for numbers - Use
RoundedRectangle(cornerRadius:style: .continuous)for shapes — never.circular - Use semantic
AppThemecolors instead of white-opacity ladders so contrast remains correct in every appearance. - Animations should be scoped with
.animation(.spring(...), value: someState). AvoidwithAnimation { state = ... }insideonAppear— that leaks the transaction onto sibling state changes (causes "bouncing" siblings) - Haptics: use
.sensoryFeedback(.selection, trigger: value)on selectable controls and.impact(weight: .light)on tap-to-refresh actions
- Connection routing:
VercelticsAppopensMainTabViewwhen at least one hosting, registrar, or site-service account exists. With no connections it opensFirstConnectionFlow: a one-time welcome followed by theLoginViewprovider catalog. Existing connected users and active subscribers are migrated past the welcome. - Soft paywall: connection, account switching, search, refresh, scrolling, and workspace-list browsing stay available without Pro. Opening item details, provider dashboards, API catalogs, or guarded actions presents the reusable paywall sheet when there is no active entitlement. Don't add launch-time paywall gates.
- Rate prompt: lives in
ProjectsViewand fires once via@AppStorage("hasShownOnboardingRatePrompt")after a successful project load — works for both free and paid users. - Favicon chain:
ProjectIconperforms bounded, credential-free discovery against the project site's own HTTPS origin and otherwise draws a local fallback. Do not add third-party favicon services or probes forwww.<sub>.vercel.app; Vercel's wildcard certificate does not cover sub-subdomains and ATS will fail. - Public IPv4 helper: registrar setup uses
PublicIPv4Lookupfor a bounded, credential-free lookup. Namecheap stores the explicitly accepted, validated public IPv4 as requiredClientIpmetadata and sends it with Namecheap API requests. Name.com only writes the address to the system pasteboard after an explicit Copy action; it must never save or send it as an API credential. - Domain resolution: when a project's bulk listing only shows
*.vercel.app,enrichProjectsNeedingDomainRefreshcalls/v9/projects/{id}/domainsand merges the verified entries into the project's alias array soprimaryDomainpicks the best one. - Sites cache: site-service snapshots may be written to the file-protected, backup-excluded Application Support cache. Credentials and OAuth tokens must never be moved out of the Keychain.
- Bug fixes
- Performance improvements
- Better error handling
- Accessibility improvements
- UI polish
- Provider dashboards, integrations, and data breakdowns supported by the relevant official API
- Safer operation coverage and provider-catalog updates with tests
- Localizations
- New framework dot colors in
ProjectCard.frameworkColors
- Third-party dependencies
- Major architecture changes without discussion
- Features that don't align with the app's purpose
- One-off colors or cards that bypass the adaptive
AppThemesystem - Credential proxies, provider-data telemetry, or third-party favicon services
- Launch-time paywalls — the soft paywall flow is deliberate
- Weekly subscription tiers — at sub-$5 monthly the abuse cost is too low to deter, and the dev community treats weekly subs in tooling apps as a red flag. Trial is yearly-only on purpose.
Open an issue at github.com/apoorvdarshan/verceltics/issues with:
- What happened
- What you expected
- Steps to reproduce
- iOS version and device
For security vulnerabilities, please follow SECURITY.md instead — do not open a public issue.
- Email: ad13dtu@gmail.com
- X: @apoorvdarshan
- LinkedIn: Verceltics
- Support: ko-fi.com/apoorvdarshan
By contributing, you agree that your contributions will be licensed under the MIT License.