Articles · GuidesUpdated October 2026

A React Native project has nine things that are yours and two directories that are output.

Expo's own documentation lists nine entries for a new project: the app directory, components, constants, hooks, assets, scripts, app.json, package.json and tsconfig.json. The android and ios directories are not on that list, because a new project does not have them. A command generates them when something needs to compile, and they are added to .gitignore for you. Learn that one line and most of the confusion about a React Native project structure goes away, including the question of which files you are allowed to touch. If you are reading this because someone handed you the codebase, start with who owns AI generated code.

What follows is the whole list, the two directories that regenerate, and the four mistakes that cost real time. Every file name and sentence quoted below comes from React Native's and Expo's own documentation, read on 17 October 2026.

Start here

The short version

One line runs through the folder tree, and it is source against output.

On one side of the line: your screens, your components, your assets, and three configuration files. You wrote them or a generator wrote them for you, and they are the whole app as far as you are concerned. On the other side: the android and ios directories, and node_modules. Those are produced from the first side by a command. A change you make there does not survive, and nothing you need is lost when they vanish.

Expo calls the mechanism Continuous Native Generation. Its own description of the problem it solves reads like a description of your situation: when bootstrapping a native app, there is initial code and configuration that you may not understand, yet you are not responsible for maintaining it. The catch is in the next sentence, which says you will eventually need to understand that code to upgrade safely. This page is about knowing which half that is.

What is actually in a React Native and Expo project?

Nine entries, in the list Expo publishes on its Start developing page. The app directory, components, constants and hooks, which in a current project sit together under a src folder. Then assets and scripts at the root, and three files: app.json, package.json and tsconfig.json. That is it. The page describes the app directory as containing the app's navigation, which is file based, and says the file structure of that directory determines the navigation.

React Native's own documentation is the quieter half of the answer, and worth knowing before you go looking for a definitive tree. It does not describe a project in any detail. It describes a Framework instead. Its getting started page says the best way to experience React Native is through a Framework, a toolbox with all the necessary APIs to build production ready apps, and names Expo as the one most developers benefit from. The page that covers going without one points you at the Community CLI and mentions exactly one file by name, App.tsx. So if you were hoping React Native would tell you what your project contains, it will not. Expo will, because the structure is the Framework's, not the renderer's.

That split explains something people trip over. Expo describes the Framework as providing file based routing, universal libraries, and the ability to write plugins that modify native code without having to manage native files. React Native says the alternative route is building an app with Android Studio and Xcode. Your project is on the first road. It looks like a web project because the Framework arranged for it to, and the native parts are downstream of configuration rather than things you open in an IDE.

React Native, get started with React Native, read 17 October 2026

Check yours

Source, output, or installed

Pick anything you can see in the project root. The first nine are the entries Expo's own documentation lists for a new project. The last three are not on it.

Yours to edit

Source, and every file in it is a screen

Expo Router turns this directory into your navigation. A file here has a default export that defines a page, apart from the _layout files. Put a helper in here by accident and Expo Router will try to treat it as a route.

Which directories are generated output rather than source?

The android and ios directories. Expo's page on Continuous Native Generation, last updated 25 September 2026 and read on 17 October, says that running npx expo prebuild creates the android and ios directories for running your React code. It adds the warning in the same paragraph: if you modify the generated directories manually then you risk losing your changes the next time you run prebuild with the clean option. The clean option deletes the existing native directories before generating new ones, and it is the option Expo recommends in most cases.

Two further details settle the question of whether they are really output. First, the documentation says the directories are automatically added to .gitignore when you create a new project, and tells you to add them yourself if they are not there. Second, in explaining how the idea compares to static site generation, Expo writes that the native project is generated on demand and that the generated source code and configuration are discarded once the native project is compiled into a native app. A folder that is deleted after the build is finished is not where your work belongs.

node_modules is the third thing in the project you did not write. It comes from package.json and your lockfile, and your package manager puts it there. Expo recommends installing libraries with npx expo install rather than npm install directly, because that picks a version compatible with your project and warns you about known incompatibilities. The same package.json is what autolinking reads to find native modules, which is how a camera library ends up wired into a native project you never opened.

So the honest inventory of a handed over project is short. There is a folder of screens, a folder or three of shared code, some images, and three configuration files. Everything else is a product of those. That also means the backup question has a simple answer. If your repository has the nine entries in it, you have the app. The rest can be rebuilt by a command, including the parts that take the longest to compile.

Expo, Continuous Native Generation, last updated 25 September 2026, read 17 October 2026

Do you have to care about the native folders at all?

Most weeks, no. The route into the native side is app.json. Expo describes the app config as the file used for configuring prebuild generation, for how a project loads in Expo Go, and for the over the air update manifest, and says it must sit at the root next to package.json. Change the icon, the app name, the splash screen or the deep link scheme there, and the generated project picks it up. For anything the config does not cover, the documented route is a config plugin, described as a function that performs modifications on native projects during prebuild. Both of those are source files. Neither is a file in the ios folder.

There is one decision in here that has consequences, and it is about git. Expo's documentation says a cloud build will run prebuild to generate the native directories when the project does not contain them, and will not run prebuild when the project does, to avoid overwriting changes you made in there. Commit android and ios, and you have taken that job on. Keep them out, and the template that matches your SDK version keeps doing it. That is the actual reason the recommendation exists. It is not tidiness.

It also changes what an upgrade feels like. Expo describes the prebuild version of upgrading as much closer to upgrading a pure JavaScript application: bump the versions in package.json, regenerate the native project, and carry on. The engine and the rendering layer underneath are part of that regeneration, which is why Hermes and the new architecture are things you configure rather than install. The same separation is what makes over the air updates possible at all: your JavaScript is a bundle the native shell loads, so some changes ship without a new native build and some do not.

What does it cost you to ignore the structure?

Four specific bills, and all four are avoidable. The first is a change that disappears. You open the ios folder, fix something in a native file, and it works. Then a dependency changes, prebuild runs with the clean option, and your fix is gone with no error message to explain it. Expo warns about exactly this. The second is the phantom screen. Expo Router treats the app directory as routes only, and says that a non-route placed inside it will be treated like a route. A utility file dropped in there becomes a page in your navigation.

The third is version drift. Install a library with npm install and you get the newest version, which may not be the one your SDK expects. Expo recommends npx expo install because it picks a compatible version and warns you about known incompatibilities. Prebuild will also warn you when your React and React Native versions differ from the ones its template expects. Those warnings are worth reading. They are the cheapest version of a problem that otherwise appears as a build failure in a log you cannot read.

The fourth is the search for a file that is not there. People look for App.tsx and cannot find it. Expo Router's core concepts page explains why: the root _layout.tsx inside the app directory is rendered before any other route, and it is where initialisation code that used to live in App.jsx now goes, including font loading, theme providers and the splash screen. There is also no code that names your first screen. The router opens the first index.tsx that matches the slash URL. Knowing those two facts turns half an hour of hunting into a single file open, and it is worth knowing before the first time you need to work out what it costs to publish an app.

Who wrote each part, and what survives a regeneration

In the project rootWho put it thereYours to editSurvives a clean prebuild
src, or app at the root in older projectsYou, or whatever generated the projectYesYes
app.jsonYou, and config plugins read itYesYes
package.jsonYou, usually through npx expo installYesYes, though prebuild may change versions
android and iosnpx expo prebuild, from a templateNoNo
node_modulesYour package managerNoReinstalled when dependencies change

Where this lands if a builder generated your app

Nothing in the layout changes because software wrote the first version. Newly generates a real React Native and Expo project you own, with two way GitHub sync, so the thing you inherit is a normal project of the shape described above. The same line between source and output applies, the same warning about editing generated directories applies, and the same nine entries are the ones worth reading first. If you can find the app directory and app.json, you can find your way around.

What a builder actually saves you is the first pass over files nobody enjoys writing. It uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK, so the native output gets produced without you learning the generation step first. It is $25 a month, with no free tier. The honest limit is the submission itself. Newly does not submit to the App Store for you, because App Store Review Guideline 4.2.6 requires an app made with an app generation service to be submitted by the owner of the app's content, and that is you.

The practical advice for anyone handed one of these projects is the same whoever typed it. Read app.json first, because it is the file with the most leverage per line. Read the app directory second, because the file names are the screens. Leave the native folders closed until something forces you to open them, and when it does, look for a config plugin before you look for a file to edit by hand. That order is not a style preference. It is what the tool expects, and working with it is cheaper than working around it.

Questions people ask about React Native project structure

Fewer things than the folder tree suggests. Expo's own Start developing page lists nine entries for a new project: src/app, src/components, src/constants, src/hooks, assets, scripts, app.json, package.json and tsconfig.json. That is the whole list, read on 17 October 2026. The android and ios directories are not on it, because a new project does not have them. React Native's own documentation barely describes a project at all. Its page on getting started without a framework names exactly one file, App.tsx, and sends you to the Community CLI to make the rest.

Describe the app, then read the nine files

A generated project is still a project you have to live in. Knowing which half of it regenerates is the difference between an afternoon of changes and an afternoon of lost work.

Start building