Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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