---
title: Language-Specific
description: This document outlines the language-specific conventions for the Formbricks codebase, providing guidelines for writing code in TypeScript/JavaScript.
icon: code
---

## TypeScript

Our codebase follows the Vercel Engineering Style Guide conventions.

### ESLint Configuration

We maintain three primary ESLint configurations for different project types:

1. **Library Configuration** (for packages):

```javascript
extends: [
"@vercel/style-guide/eslint/node",
"@vercel/style-guide/eslint/typescript"
]
```

2. **React Configuration** (for React applications):

```javascript
extends: [
"@vercel/style-guide/eslint/node",
"@vercel/style-guide/eslint/typescript",
"@vercel/style-guide/eslint/browser",
"@vercel/style-guide/eslint/react",
"@vercel/style-guide/eslint/next"
]
```

3. **Next.js Configuration** (for Next.js applications):

```javascript
extends: [
"@vercel/style-guide/eslint/node",
"@vercel/style-guide/eslint/typescript",
"@vercel/style-guide/eslint/browser",
"@vercel/style-guide/eslint/react",
"@vercel/style-guide/eslint/next"
]
```

### Key Conventions

1. **TypeScript Usage**

   - Strict TypeScript checking enabled
   - Explicit type annotations when necessary
   - Proper interface and type naming (prefix with T for types, I for interfaces when helpful)
   - No use of `any` type unless absolutely necessary

2. **Imports/Exports**

   - Follow strict import ordering:
     1. Mocks (for testing)
     2. Server-only imports
     3. Third-party modules
     4. Internal `@formbricks/*` modules
     5. Local aliases (`~/*`)
     6. Relative imports

3. **Error Handling**

   - Use typed error responses
   - Proper error propagation
   - Consistent error message formatting
   - Implement error boundaries in React components

4. **Async/Await**

   - Prefer async/await over raw promises
   - Proper error handling in async functions
   - Use Promise.all for parallel operations

5. **React Specific**
   - Functional components with TypeScript
   - Proper use of hooks
   - Consistent prop typing
   - Server Components by default in Next.js App Router

### Code Formatting

We use Prettier with specific configurations:

```javascript
{
bracketSpacing: true,
bracketSameLine: true,
singleQuote: false,
jsxSingleQuote: false,
trailingComma: "es5",
semi: true,
printWidth: 110,
arrowParens: "always"
}
```

## Swift (iOS SDK)

Our iOS SDK follows Swift best practices.

### Swift Configuration

The iOS SDK requires the following:

- **Swift Version**: 5.7+
- **Platform**: iOS 16.6+
- **Package Manager**: Swift Package Manager and CocoaPods support
- **ARC**: Automatic Reference Counting enabled

**Package.swift Configuration:**

```swift
// swift-tools-version:5.7
platforms: [
  .iOS(.v16)
],
```

**CocoaPods Configuration:**

```ruby
s.platform = :ios, "16.6"
s.swift_version = "5.7"
s.requires_arc = true
```

### Key Conventions

1. **Access Control Strategy**

   - `public`: SDK public API surface only
   - `internal`: Internal SDK communication and shared components
   - `private`: Implementation details within specific classes
   - Strategic use of `private(set)` for read-only public properties

2. **Architecture Patterns**

   - **Singleton Pattern**: Main SDK class (`Formbricks`) with static interface
   - **Manager Pattern**: Specialized managers (`UserManager`, `SurveyManager`, `PresentSurveyManager`)
   - **Builder Pattern**: Configuration objects (`FormbricksConfig.Builder`)
   - **Protocol-Oriented Programming**: Service protocols for dependency injection and testing

3. **Error Handling**

   - Custom error enums with descriptive cases (`FormbricksSDKErrorType`)
   - Error types conform to `LocalizedError` protocol
   - Structured error propagation with completion handlers
   - Defensive programming with guard statements and early returns

4. **Naming Conventions**

   - Classes: PascalCase (`FormbricksConfig`, `UserManager`)
   - Properties/Methods: camelCase (`environmentId`, `setUserId`)
   - Constants: camelCase with descriptive names
   - Protocol names: Descriptive with "Protocol" suffix (`FormbricksServiceProtocol`)

5. **Code Organization**

   - `// MARK:` comments for logical section separation
   - Extensions for related functionality grouping
   - Consistent file structure with models, managers, networking, and views

6. **Model Design**

   - Prefer `struct` for data models and value types
   - Use `class` for reference types and managers
   - Implement `Codable` for JSON serialization/deserialization
   - Immutable properties where possible (`let` over `var`)

7. **Security & Validation**

   - HTTPS enforcement for all network requests
   - URL validation before network operations
   - Input validation with descriptive error messages
   - Secure data handling practices

8. **Asynchronous Operations**
   - `OperationQueue` for network operations
   - Completion handlers for async operations
   - Network connectivity checking with `NWPathMonitor`
   - Thread-safe operations with proper queue management

### Code Formatting

We follow standard Swift formatting conventions:

**Key Formatting Rules:**

```swift
// Class definitions
@objc(Formbricks) public class Formbricks: NSObject {

// Property declarations with access control
static internal var isInitialized: Bool = false
private let userManager: UserManager

// Method signatures with clear parameter labels
@objc public static func setup(with config: FormbricksConfig, force: Bool = false)

// Guard statements for early returns
guard !isInitialized else {
    let error = FormbricksSDKError(type: .sdkIsAlreadyInitialized)
    Formbricks.logger?.error(error.message)
    return
}

// Enum cases with descriptive names
public enum FormbricksSDKErrorType: Int {
    case sdkIsNotInitialized
    case invalidAppUrl
    case networkError
}
```

## Kotlin (Android SDK)

Our Android SDK codebase with Kotlin follows modern Android development practices and Kotlin conventions.

### Key Conventions

1. **Package Structure**

   - Logical grouping by functionality (api, model, network, manager, webview)
   - Clear separation of concerns across packages

2. **Kotlin Language Features**

   - **Object singletons** for stateless utilities and managers (`Formbricks`, `Logger`, `SDKError`)
   - **Data classes** for models with automatic equals/hashCode/toString (`Survey`, `User`)
   - **Sealed classes** for representing restricted hierarchies
   - **Extension functions** for utility methods (`Guard.kt`, `DateExtensions.kt`)
   - **Coroutines** for asynchronous operations with proper context switching

3. **Error Handling**

   - Centralized error definitions in `SDKError` object
   - Use of `Result<T>` type for API responses
   - Proper exception propagation with meaningful error messages
   - Consistent error logging through centralized `Logger`

4. **Android-Specific Patterns**

   - `@Keep` annotations for ProGuard/R8 compatibility on public APIs
   - Proper lifecycle management in fragments and view models
   - Use of `FragmentManager` for UI components
   - Network security configuration for HTTPS enforcement

5. **Async/Await Pattern**

   - Prefer coroutines with `suspend` functions over callbacks
   - Use `withContext(Dispatchers.IO)` for network operations
   - Implement retry logic with `delay()` for robust API calls
   - Proper error handling in async functions

6. **API and Network Layer**
   - Retrofit for HTTP client with Gson converter
   - OkHttp interceptors for logging and security
   - Proper timeout configurations
   - Result-based API responses with retry mechanisms

### Code Formatting

We use Android Studio's default Kotlin formatting

### Data Modeling

1. **Serialization**

   - Kotlinx Serialization for modern JSON handling
   - Gson annotations for backward compatibility: `@SerializedName`
   - Consistent nullable and non-nullable field declarations

2. **Data Classes**
   - Immutable data structures where possible
   - Proper use of nullable types (`String?`)
   - Clear property naming and documentation
