This is a starter project along with boilerplate code which aims to create scalable, robust and enterprise level React Native Typescript applications 🚀
-
Pre configured react-native-storybook 📙. Launch the app and toggle the UI between storybook and react native!
Moreover, there will not be any manual effort needed for importing story entries thanks to react-native-storybook-loader library.
- Storybook scripts in package.json
"storybook": "start-storybook -p 6006", "prestorybook": "rnstl" // react-native-storybook-loader
- Storybook scripts in package.json
-
Detox 🤖 for gray box end-to-end testing.
- Detox scripts in package.json
"test:e2e": "detox test -c ios.sim.debug", "build:e2e": "detox build -c ios.sim.debug", "ci:test:e2e": "detox test -c ios.sim.release -l verbose --cleanup", "ci:build:e2e": "detox build -c ios.sim.release",
- Detox scripts in package.json
-
React native, typescript specific robust eslint configurations to enhance development experience.
- Some of eslint configurations are the followings:
-
Debugging 🛠 is one of the fundamental phase of development. Reactotron is ready for this purpose already!
-
Initializing navigation packages in react native applications can be overwhelming and time consuming. React navigation v6 is already installed and initialized along with required packages such as react-native-screens, using strongly typed typescript.
-
It is significant to write a good commit message, especially when you are collaborating with a team or a developer. Here comes Commitlint. It is initialized with the base config!
-
There might be specific scenarios that some actions might need to be executed before committing or pushing the code. Husky ⚓️ will take the responsibility for improving the commits along with commitlint. Husky with commitlint is 💣.
Nested folders can be seen more frequently if the project gets larger by the time goes on.
And the path for importing any module from deeper component could be the following:
import AppButton from "../../../../../components/button/app-button"
Fortunately, Babel plugin module resolver with typescript resolves this issue with some quick configurations which is already covered in this project.
import AppButton "@/components/button/app-button"
The project folder structure is the following.
src
|-- api
| |-- axios.instance.ts
|-- app.tsx
|-- assets
| |-- data-uris.ts
| |-- fonts
| |-- images
| |-- index.ts
|-- components
| |-- button
| | |-- button.stories.tsx
| | |-- button.test.tsx
| | |-- button.tsx
| | |-- index.ts
| |-- safe-area
| | |-- index.ts
| | |-- safe-area-provider.tsx
| | |-- safe-area-view.tsx
| |-- shared
| | |-- banner
| | | |-- banner.stories.tsx
| | | |-- banner.test.tsx
| | | |-- banner.tsx
| | | |-- index.ts
|-- config
| |-- reactotron.ts
|-- index.ts
|-- lib
| |-- async-storage
| | |-- index.ts
| |-- constants
| | |-- index.ts
| | |-- regex.ts
| | |-- validation.ts
| |-- user
| | |-- index.ts
| | |-- user.interface.ts
|-- localization
| |-- constants
| | |-- langauge.ts
| |-- helpers
| | |-- language-resources.ts
| | |-- language.ts
| |-- i18n.ts
| |-- locales
| | |-- de_DE.json
| | |-- en_US.json
|-- navigation
| |-- helpers
| | |-- tabbar-options.tsx
| | |-- tabbar-routes.ts
| |-- root-navigator.tsx
| |-- route-names.ts
| |-- stacks
| | |-- auth.tsx
| | |-- home.tsx
| | |-- profile.tsx
| |-- tabbar.tsx
| |-- types
| | |-- auth.ts
| | |-- home.ts
| | |-- index.ts
| | |-- profile.ts
| | |-- tabbar.ts
|-- screens
| |-- error
| | |-- fallback-screen.tsx
| | |-- index.ts
| | |-- main-error-boundary.tsx
| |-- home
| | |-- helpers
| | | |-- index.ts
| | |-- home-screen.tsx
| | |-- hooks
| | | |-- index.ts
| | |-- index.ts
| |-- launch
| | |-- index.ts
| | |-- launch-screen.tsx
| |-- login
| | |-- index.ts
| | |-- login-screen.tsx
| |-- profile
| | |-- index.ts
| | |-- profile-screen.tsx
| |-- sign-up
| | |-- index.ts
| | |-- sign-up-screen.tsx
|-- scripts
| |-- setup-debug.ts
|-- theme
| |-- common-styles.ts
|-- types
| |-- env.d.ts
|-- utils
| |-- ignore-logs.ts
| |-- index.ts
| |-- list.ts
| |-- network-activity.ts
| |-- storybook
| | |-- index.ts
| | |-- withStorybook.tsx
At first glance, some may think; "Hey, React suggests PascalCase for React components! Why you did not use PascalCase here ?"
First thing can be noticed easily is that all of the file names are named in kebab-case convention. There are several reasons behing this decision. One of them is related to CI system. This might not look reasonable for everyone though.
Having solely one naming convention throughout the project looks more solid and professional. Rather than using PascalCase (AppHeader.tsx) or kebap-case (header-utils.ts) depending on the situtation, having all file names with single naming convention is a way to go.
There is no BETTER naming convention or you MUST use this naming convention rule.
Therefore, feel free not to stick with kebap-case naming convention.
git clone https://github.com/tarikpnr/react-native-typescript-starter.git
Project react native
version: 0.68.1
Project react
version: 17.0.2
If you have any feedback, please reach out to me at tarikdotcom@gmail.com