Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup Node.js 22.x
- name: Setup Node.js 24.x
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 22.x
node-version: 24.x

- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Lint and Type Check
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
merge_group:
permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Harden the runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit

- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup Node.js 24.x
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 24.x

- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm lint

- name: Check types
run: pnpm check-types
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm lint

- name: Check types
run: pnpm check-types

- name: Build package
run: |
cd packages/react-native
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup Node.js 22.x
- name: Setup Node.js 24.x
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 22.x
node-version: 24.x

- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
Expand Down
34 changes: 34 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Repository Guidelines

## Project Structure & Module Organization
This repository is a `pnpm` workspace with two main packages:

- `packages/react-native`: the published SDK (`@formbricks/react-native`). Source lives in `src/`, grouped by domain under `src/lib/`, with React components in `src/components/` and shared types in `src/types/`.
- `apps/playground`: an Expo app for manual testing and integration checks. App code is in `src/`, with static assets in `assets/`.

GitHub Actions under `.github/workflows/` enforce build, lint, type-check, test, and release steps.

## Build, Test, and Development Commands
Run commands from the repository root unless package-scoped work is needed.

- `pnpm install --frozen-lockfile`: install workspace dependencies.
- `pnpm dev`: run Turbo watchers across packages.
- `pnpm build`: build the SDK and playground.
- `pnpm lint`: enforce exact dependency versions, then run Biome checks.
- `pnpm check-types`: run TypeScript checks across the workspace.
- `pnpm test`: run unit tests with Vitest.
- `pnpm test:coverage`: generate coverage reports used in release validation.
- `pnpm --filter playground ios` / `pnpm --filter playground android`: launch the Expo playground on a device target.

## Coding Style & Naming Conventions
Use TypeScript with strict compiler settings. Biome is the formatter and linter; run `pnpm format` before large refactors. The repo uses spaces for indentation, double quotes, and semicolons.

Follow existing naming patterns: React components in lowercase kebab-style filenames such as `survey-web-view.tsx`, domain modules in concise lowercase names such as `state.ts`, and tests as `*.test.ts`. Keep imports using the `@/` alias inside `packages/react-native` when referencing `src/`.

## Testing Guidelines
Unit tests live beside each domain under `src/lib/**/tests/`. Prefer small, focused Vitest suites and place reusable doubles in local `__mocks__/` folders. Add or update tests with every behavior change; there is no published coverage threshold, but `test:coverage` is part of the release workflow, so changed code should stay covered.

## Commit & Pull Request Guidelines
Recent history mostly follows Conventional Commit-style subjects such as `feat:`, `fix:`, and `chore:` with short imperative summaries. Keep commits narrowly scoped and descriptive.

PRs should include a clear summary, linked issue if applicable, and the commands you ran locally (`pnpm lint`, `pnpm check-types`, relevant tests). Include screenshots or screen recordings when a playground or UI behavior changes. Avoid loose dependency ranges: this repo enforces exact versions in every `package.json`.
7 changes: 0 additions & 7 deletions apps/playground/.eslintrc.js

This file was deleted.

5 changes: 0 additions & 5 deletions apps/playground/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
"assetBundlePatterns": ["**/*"],
"icon": "./assets/icon.png",
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "Take pictures for certain activities.",
"NSMicrophoneUsageDescription": "Need microphone access for recording videos.",
"NSPhotoLibraryUsageDescription": "Select pictures for certain activities."
},
"supportsTablet": true
},
"jsEngine": "hermes",
Expand Down
15 changes: 8 additions & 7 deletions apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@
"android": "expo start --android",
"ios": "expo start --ios",
"clean": "rimraf .turbo node_modules .expo",
"build": "expo export --no-bytecode"
"build": "expo export --no-bytecode",
"check-types": "tsc --noEmit"
},
"dependencies": {
"@formbricks/react-native": "workspace:*",
"@react-native-async-storage/async-storage": "2.2.0",
"expo": "54.0.33",
"expo-status-bar": "3.0.9",
"@react-native-async-storage/async-storage": "3.0.2",
"expo": "55.0.9",
"expo-status-bar": "55.0.4",
"react": "19.2.4",
"react-native": "0.84.0",
"react-native-webview": "13.16.0"
"react-native": "0.84.1",
"react-native-webview": "13.16.1"
},
"devDependencies": {
"@babel/core": "7.29.0",
"@types/react": "19.2.14",
"typescript": "5.9.3"
"typescript": "6.0.2"
},
"private": true
}
8 changes: 4 additions & 4 deletions apps/playground/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { StatusBar } from "expo-status-bar";
import React, { type JSX } from "react";
import { Button, LogBox, StyleSheet, Text, View } from "react-native";
import Formbricks, {
logout,
setAttribute,
Expand All @@ -9,6 +6,9 @@ import Formbricks, {
setUserId,
track,
} from "@formbricks/react-native";
import { StatusBar } from "expo-status-bar";
import type { JSX } from "react";
import { Button, LogBox, StyleSheet, Text, View } from "react-native";

LogBox.ignoreAllLogs();

Expand Down Expand Up @@ -74,7 +74,7 @@ export default function App(): JSX.Element {
(error: unknown) => {
// eslint-disable-next-line no-console -- logging is allowed in demo apps
console.error("Error setting user attributes:", error);
}
},
);
}}
/>
Expand Down
34 changes: 34 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.9/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"includes": [
"**",
"!**/coverage",
"!**/dist",
"!**/.expo",
"!**/node_modules"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always"
}
}
}
23 changes: 7 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,20 @@
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "node scripts/check-exact-deps.mjs && turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"lint": "node scripts/check-exact-deps.mjs && biome check .",
"format": "biome format --write .",
"check-types": "turbo run check-types",
"test": "turbo run test --no-cache",
"test:coverage": "turbo run test:coverage --no-cache"
},
"devDependencies": {
"prettier": "3.8.1",
"turbo": "2.8.20",
"typescript": "5.9.3",
"@biomejs/biome": "2.4.9",
"turbo": "2.8.21",
"typescript": "6.0.2",
"rimraf": "6.1.3"
},
"packageManager": "pnpm@10.32.1",
"packageManager": "pnpm@10.33.0",
"engines": {
"node": ">=20.19.0"
},
"pnpm": {
"overrides": {
"on-headers": "1.1.0",
"glob": "13.0.4",
"node-forge": "1.3.3",
"js-yaml": "4.1.1",
"tar": "7.5.12"
}
"node": "^20.19.0 || >=22.12.0"
}
}
40 changes: 0 additions & 40 deletions packages/react-native/.eslintrc.cjs

This file was deleted.

27 changes: 13 additions & 14 deletions packages/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,32 @@
}
},
"scripts": {
"build": "tsc && vite build",
"build:dev": "tsc && vite build --mode dev",
"lint": "eslint src --ext .ts,.js,.tsx,.jsx",
"build": "rimraf dist tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && vite build",
"build:dev": "rimraf dist tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && vite build --mode dev",
"lint": "biome check .",
"dev": "vite build --watch --mode dev",
"clean": "rimraf .turbo node_modules dist .turbo",
"clean": "rimraf .turbo node_modules dist tsconfig.build.tsbuildinfo",
"check-types": "tsc -p tsconfig.json --noEmit",
"test": "vitest",
"test:coverage": "vitest run --coverage"
},
"dependencies": {
"@react-native-community/netinfo": "11.5.2",
"@react-native-community/netinfo": "12.0.1",
"zod": "4.3.6"
},
"devDependencies": {
"@types/node": "24.7.2",
"@types/react": "19.2.14",
"@vercel/style-guide": "6.0.0",
"@vitest/eslint-plugin": "1.6.12",
"@vitest/coverage-v8": "4.0.18",
"@vitest/coverage-v8": "4.1.2",
"react": "19.2.4",
"react-native": "0.84.0",
"terser": "5.46.0",
"vite": "7.3.1",
"vite-plugin-dts": "4.5.4",
"vitest": "4.0.18"
"react-native": "0.84.1",
"typescript": "6.0.2",
"tsc-alias": "1.8.16",
"vite": "8.0.3",
"vitest": "4.1.2"
},
"peerDependencies": {
"@react-native-async-storage/async-storage": ">=2.1.0",
"eslint": "8.57.0",
"react": ">=16.8.0",
"react-native": ">=0.60.0",
"react-native-webview": ">=13.0.0"
Expand Down
8 changes: 6 additions & 2 deletions packages/react-native/src/components/formbricks.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useEffect, useSyncExternalStore } from "react";
import type React from "react";
import { useCallback, useEffect, useSyncExternalStore } from "react";
import { View } from "react-native";
import { SurveyWebView } from "@/components/survey-web-view";
import { Logger } from "@/lib/common/logger";
Expand All @@ -13,7 +14,10 @@ interface FormbricksProps {
const surveyStore = SurveyStore.getInstance();
const logger = Logger.getInstance();

export function Formbricks({ appUrl, environmentId }: FormbricksProps): React.JSX.Element | null {
export function Formbricks({
appUrl,
environmentId,
}: FormbricksProps): React.JSX.Element | null {
// initializes sdk
useEffect(() => {
const setupFormbricks = async (): Promise<void> => {
Expand Down
Loading
Loading