Skip to content

Create scalable, robust and enterprise level React Native Typescript applications πŸš€

License

Notifications You must be signed in to change notification settings

tarikfp/react-native-typescript-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

React Native Typescript Starter

This is a starter project along with boilerplate code which aims to create scalable, robust and enterprise level React Native Typescript applications πŸš€

Table of contents

What is in it?

  • 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
      
  • 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",
      
  • React native, typescript specific robust eslint configurations to enhance development experience.

  • 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 πŸ’£.

Packages πŸŽ‰

Running e2e test πŸ€–

There is an already initial setup for e2e test in the project. Make sure you run the build script for detox beforehand, then simply executing detox test will have the following result.

Code
const { reloadApp } = require("./reload");

describe("Example", () => {
  beforeEach(async () => {
    await reloadApp();
  });

  it("should have welcome screen", async () => {
    await expect(element(by.id("WelcomeScreen"))).toBeVisible();
  });

  it("should tap the button and counter should be increased by one", async () => {
    await element(by.id("tap-me")).tap();
    await expect(element(by.id("counter"))).toHaveText("1");
  });
});

Storybook usage πŸ“™

Toggle between storybook and app seamlessly!

Path resolver

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"

Folder structure

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.

Personal thoughts regarding the naming convention

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.

Usage

  • Clone the project
git clone https://github.com/tarikpnr/react-native-typescript-starter.git

Example apps

Screenshots

Contributing

The main purpose of this library is to provide a highly scalable, robust and bug-free react native project. Contributors are always highly appreciated to keep this library maintained and enhance it more.

License

MIT

About

Create scalable, robust and enterprise level React Native Typescript applications πŸš€

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published