Home

Awesome

<div align="center"><h1>React Native Typescript Starter</h1></div> <div align="center"><p1 align="center">This is a starter project along with boilerplate code which aims to create scalable, robust and enterprise level React Native Typescript applications 🚀</p1></div>

Table of contents

What is in it?

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.

<img src="./screenshots/detox-first-test.gif"/> <details><summary>Code</summary>
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");
  });
});
</details>

Storybook usage 📙

Toggle between storybook and app seamlessly!

<img src="./screenshots/storybook-usage.gif"/>

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

git clone https://github.com/tarikpnr/react-native-typescript-starter.git

Example apps

Screenshots

<table> <tr> </tr> <tr> <td><img src="./screenshots/app-home-screen.png"></td> <td><img src="screenshots/app-profile-screen.png"></td> <td><img src="screenshots/storybook-banner-knobs.png"></td> </tr> <tr> <td><img src="./screenshots/storybook-banner.png"></td> <td><img src="screenshots/storybook-button-knobs.png"></td> <td><img src="screenshots/storybook-button.png"></td> </tr> <tr> <td><img src="./screenshots/storybook-navigator.png"></td> <td><img src="screenshots/storybook-main-screen.png"></td> </tr> </table>

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