Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cf305a7
chore: upgrade expo
drobilc Jun 30, 2025
e93482d
chore: upgrade expo to `^53.0.13`
drobilc Jun 30, 2025
7a33364
fix: sentry configuration
drobilc Jun 30, 2025
d6a6867
fix: updated router typing for router v4
VaneSkubic Jun 30, 2025
e38ac8c
Merge branch 'chore/update-project' of github.com:zerodays/react-nati…
VaneSkubic Jun 30, 2025
1fd89c6
fix: removed generics for Href (new version)
VaneSkubic Jun 30, 2025
f900d68
feat: extend FormTextInputProps to include optional style prop
drobilc Jun 30, 2025
2d3f262
fix: remove unused axios instance
drobilc Jun 30, 2025
20d03c0
fix: changed route declaration
VaneSkubic Jun 30, 2025
d9bbe36
Merge branch 'chore/update-project' of github.com:zerodays/react-nati…
VaneSkubic Jun 30, 2025
bb14422
fix: remove trailing slash from routes
drobilc Jun 30, 2025
6d2e3a5
chore: update nativewind
VaneSkubic Jun 30, 2025
c6cb946
Merge branch 'chore/update-project' of github.com:zerodays/react-nati…
VaneSkubic Jun 30, 2025
c77d497
chore: updated outdated dependencies
VaneSkubic Jun 30, 2025
44eeaf3
chore: updated tailwind to v4
VaneSkubic Jun 30, 2025
2a40937
fix: fixed tailwind - nativewind version mismatch
VaneSkubic Jun 30, 2025
a103d3e
fix: reverted tailwind v4 syntax fixes
VaneSkubic Jun 30, 2025
a151818
chore: updated zustand dependency
VaneSkubic Jun 30, 2025
2f182c7
chore: remove fixed yarn version in `package.json`
VaneSkubic Jun 30, 2025
b0b5802
chore: upgraded eslint, prettier and downgraded sentry
VaneSkubic Jun 30, 2025
c88a101
chore: updated github workflow node version
VaneSkubic Jun 30, 2025
14b9284
chore: build commit
VaneSkubic Jun 30, 2025
8a974c0
chore: revert eslint version
VaneSkubic Jun 30, 2025
d23d051
chore: ran `yarn format-fix`
VaneSkubic Jun 30, 2025
b59e622
feat: upgraded yarn to latest version
VaneSkubic Jun 30, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: 🏗 Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 20.x
cache: yarn

- name: 🏗 Setup EAS
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
node-version: '20'
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Run lint
Expand All @@ -27,7 +27,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
node-version: '20'
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Run typecheck
Expand All @@ -42,7 +42,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
node-version: '20'
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Run Prettier through format
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ android/
# The following patterns were generated by expo-cli

expo-env.d.ts
# @end expo-cli
# @end expo-cli
.env.local
Binary file added .yarn/install-state.gz
Binary file not shown.
942 changes: 942 additions & 0 deletions .yarn/releases/yarn-4.9.2.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.9.2.cjs
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ yarn

## Project Structure 🏗️

This template provides a well-organized directory structure with a set of pre-configured files to streamline your development process. Here's an overview of the essential components:
This template provides a well-organized directory structure with a set of preconfigured files to streamline your development process. Here's an overview of the essential components:

- `.github`: Contains GitHub Actions workflows for CI/CD.
- `app`: Contains the screens (utilizing expo-router file naming).
Expand Down Expand Up @@ -166,7 +166,7 @@ Pre-configured routing structure for authenticated and guest users. Routes are t
```typescript
import { Href } from 'expo-router';

type RouteConstructor = <T>(href: Href<T>) => Href<T>;
type RouteConstructor = (href: Href) => Href;
const Route: RouteConstructor = (href) => href;

const Routes = {
Expand Down Expand Up @@ -281,7 +281,7 @@ These environment variables are injected into the build process using the Infisi

### Included Packages and Their Benefits 📦

The `react-native-template` includes several packages that extend its capabilities and enrich the development experience. Heres a brief overview of these packages and what they offer:
The `react-native-template` includes several packages that extend its capabilities and enrich the development experience. Here's a brief overview of these packages and what they offer:

<a name="zod"></a>

Expand All @@ -299,7 +299,7 @@ The `react-native-template` includes several packages that extend its capabiliti

#### Lucide-React-Native

[Lucide-React-Native](https://github.com/lucide-icons/lucide-react-native) is a fork of the Feather Icons project, specifically tailored for React Native applications. It provides a collection of beautifully crafted, customizable icons which are easy to use in UI development. Using Lucide icons helps maintain consistency and clarity in the apps design, making the interface more intuitive and visually appealing.
[Lucide-React-Native](https://github.com/lucide-icons/lucide-react-native) is a fork of the Feather Icons project, specifically tailored for React Native applications. It provides a collection of beautifully crafted, customizable icons which are easy to use in UI development. Using Lucide icons helps maintain consistency and clarity in the app's design, making the interface more intuitive and visually appealing.

<a name="react-hook-form"></a>

Expand Down
1 change: 1 addition & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"organization": "sentry org slug, or use the `SENTRY_ORG` environment variable",
"project": "sentry project name, or use the `SENTRY_PROJECT` environment variable"
}
Expand Down
5 changes: 4 additions & 1 deletion app/(authenticated)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Button from '@components/ui/button';
import { Loading } from '@components/ui/loading';
import { cn } from '@utils/cn';
import Routes from '@utils/routes';
import { useExampleStore } from '@utils/stores/example-store';
import useToastStore from '@utils/stores/toast-store';
import theme from '@utils/theme';
Expand Down Expand Up @@ -31,7 +32,9 @@ const AuthHomeScreen = () => {
<Button asChild onPress={() => decrement()}>
<MinusIcon color={theme.black} />
</Button>
<Button onPress={() => router.navigate('(guest)')}>Logout</Button>
<Button onPress={() => router.navigate(Routes.guest.index)}>
Logout
</Button>
<Loading />
<Button onPress={() => setToast({ type: 'success', message: 'Hello!' })}>
Show Toast
Expand Down
3 changes: 2 additions & 1 deletion app/(guest)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Button from '@components/ui/button';
import Routes from '@utils/routes';
import theme from '@utils/theme';
import { router } from 'expo-router';
import { useTranslation } from 'react-i18next';
Expand All @@ -22,7 +23,7 @@ const GuestHomeScreen = () => {
<Text>{t('helloWorld')}</Text>
<Button
variant="default"
onPress={() => router.navigate('(authenticated)')}>
onPress={() => router.navigate(Routes.auth.index)}>
Login
</Button>

Expand Down
17 changes: 7 additions & 10 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@ import * as Sentry from '@sentry/react-native';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import useCustomFonts from '@utils/hooks/use-custom-fonts';
import '@utils/i18n/config';
import Constants from 'expo-constants';
import { isRunningInExpoGo } from 'expo';
import { Slot, SplashScreen, useNavigationContainerRef } from 'expo-router';
import { useEffect } from 'react';
import '../global.css';

// Construct a new instrumentation instance. This is needed to communicate between the integration and React
const routingInstrumentation = new Sentry.ReactNavigationInstrumentation();
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(),
});

Sentry.init({
debug: true,
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
environment: process.env.EXPO_PUBLIC_SENTRY_ENV,
integrations: [
new Sentry.ReactNativeTracing({
routingInstrumentation,
enableNativeFramesTracking: Constants.appOwnership !== 'expo', // Only in native builds, not in Expo Go.
}),
],
integrations: [navigationIntegration],
enableNativeFramesTracking: !isRunningInExpoGo(),
});

const queryClient = new QueryClient();
Expand All @@ -40,7 +37,7 @@ const RootLayout = () => {

useEffect(() => {
if (ref) {
routingInstrumentation.registerNavigationContainer(ref);
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);

Expand Down
5 changes: 3 additions & 2 deletions components/ui/inputs/text.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FieldValues, Path } from 'react-hook-form';
import type { TextInputProps } from 'react-native';
import type { StyleProp, TextInputProps, ViewStyle } from 'react-native';

import clsx from 'clsx';
import type { LucideIcon } from 'lucide-react-native';
Expand All @@ -12,12 +12,13 @@ type TextInputParams = {
};

interface FormTextInputProps<TFieldValues extends FieldValues>
extends Omit<TextInputProps, 'onBlur' | 'onChangeText' | 'value'> {
extends Omit<TextInputProps, 'style'> {
name: Path<TFieldValues>;
label?: string;
icon?: LucideIcon;
params?: TextInputParams;
displayMode?: boolean;
style?: StyleProp<ViewStyle>;
}

/**
Expand Down
20 changes: 20 additions & 0 deletions env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createEnv } from '@t3-oss/env-core';
import { z } from 'zod';

const env = createEnv({
clientPrefix: 'EXPO_PUBLIC_',

client: {
// API URL for the backend service
// This is used for generating the API client with the "gen-api" command
EXPO_PUBLIC_API_URL: z.string().url('API_URL must be a valid URL'),
},

/**
* What object holds the environment variables at runtime. This is usually
* `process.env` or `import.meta.env`.
*/
runtimeEnv: process.env,
});

export default env;
25 changes: 25 additions & 0 deletions orval.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig } from 'orval';

export default defineConfig({
api: {
output: {
mode: 'split',
target: 'api/generated/endpoints.ts',
schemas: 'api/generated/model',
client: 'react-query',
clean: true,
mock: true,
prettier: true,
override: {
mutator: {
path: './api/axios-instance.ts',
name: 'customAxios',
},
},
},
input: {
// This will get overridden by /scripts/generate-api.ts
target: './placeholder.yaml',
},
},
});
61 changes: 33 additions & 28 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,68 +7,73 @@
"android": "infisical run -- expo start --android",
"ios": "infisical run -- expo start --ios",
"web": "infisical run -- expo start --web -c",
"gen-api": "infisical run --path='/frontend' --command 'openapi-zod-client \"$EXPO_PUBLIC_API_URL/docs/bundle.yml\" -o './api/index.ts' -t ./scripts/zodios-client-template.hbs' && prettier --write ./api/index.ts",
"gen-api": "infisical run --command 'tsx ./scripts/generate-api.ts'",
"lint": "eslint .",
"format-check": "prettier --check .",
"format-fix": "prettier --write .",
"prepare": "husky",
"eas-build-pre-install": "./scripts/infisical.sh"
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.23.1",
"@sentry/react-native": "~5.22.0",
"@react-native-async-storage/async-storage": "2.1.2",
"@sentry/react-native": "~6.14.0",
"@t3-oss/env-core": "^0.13.8",
"@tanstack/react-query": "^5.29.2",
"@zodios/core": "^10.9.6",
"@zodios/react": "^10.4.5",
"axios": "^1.6.8",
"clsx": "^2.1.0",
"expo": "~51.0.9",
"expo-constants": "~16.0.2",
"expo-font": "~12.0.6",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-localization": "~15.0.3",
"expo-network": "~6.0.1",
"expo-router": "~3.5.14",
"expo-status-bar": "~1.12.1",
"exp": "^57.2.1",
"expo": "^53.0.13",
"expo-constants": "~17.1.6",
"expo-font": "~13.3.1",
"expo-linear-gradient": "~14.1.5",
"expo-linking": "~7.1.5",
"expo-localization": "~16.1.5",
"expo-network": "~7.1.5",
"expo-router": "~5.1.1",
"expo-status-bar": "~2.2.3",
"i18next": "^23.10.1",
"intl-pluralrules": "^2.0.1",
"lottie-react-native": "6.7.0",
"lottie-react-native": "7.2.2",
"lucide-react-native": "^0.368.0",
"nativewind": "^4.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"nativewind": "^4.1.23",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-hook-form": "^7.51.3",
"react-i18next": "^14.1.0",
"react-native": "0.74.1",
"react-native-gesture-handler": "~2.16.1",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
"react-native": "0.79.4",
"react-native-gesture-handler": "~2.24.0",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-svg": "15.11.2",
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.4.3",
"zod": "^3.22.4",
"zustand": "^4.5.2"
"zod": "^3.25.67",
"zustand": "^5.0.6"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@eslint/js": "^9.2.0",
"@types/aes-js": "^3.1.4",
"@types/react": "~18.2.79",
"@types/react": "~19.0.10",
"@types/react-dom": "~18.2.25",
"eslint": "8",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-sonarjs": "^1.0.3",
"husky": "^9.0.11",
"openapi-zod-client": "^1.18.1",
"prettier": "^3.2.5",
"orval": "^7.10.0",
"prettier": "^3.6.2",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.5.13",
"typescript": "~5.3.3",
"tsx": "^4.20.3",
"typescript": "~5.8.3",
"typescript-eslint": "^7.9.0"
},
"private": true
"private": true,
"packageManager": "yarn@4.9.2"
}
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"compilerOptions": {
"strict": true,
"baseUrl": ".",
"moduleResolution": "bundler",
"paths": {
"@assets/*": ["assets/*"],
"@components/*": ["components/*"],
Expand All @@ -15,6 +16,7 @@
"**/*.tsx",
"**/*.js",
".expo/types/**/*.ts",
"expo-env.d.ts"
"expo-env.d.ts",
"nativewind-env.d.ts"
]
}
1 change: 0 additions & 1 deletion utils/credentials/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
This folder should contain credential files (e.g. provided by Google):

1. Firebase files (if this app uses Firebase Cloud Messaging and Firebase Crashlytics atm):

- `google-services.json` for android
- `GoogleService-Info.plist` for iOS

Expand Down
12 changes: 2 additions & 10 deletions utils/routes.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { Href } from 'expo-router';

// This is a helper function to create a route object with type safety
type RouteConstructor = <T>(href: Href<T>) => Href<T>;
const Route: RouteConstructor = (href) => href;

const Routes = {
guest: {
index: Route('/(guest)/'),
index: '/(guest)',
},
auth: {
index: Route('/(authenticated)/'),
index: '/(authenticated)',
},
} as const;

Expand Down
Loading