1. The solution folder
the top of the tree: everything hangs off this one folderInside the solution folder sit six folders as siblings: none of them is nested inside another. That flatness is the whole point of an n-tier layout: every folder holds one job, and its name tells you what it is allowed to know about.
-
project solution folder
solution folder
-
webhost
The front door: it hosts the HTTP endpoints and starts the application.
-
logic
The business rules. Nothing here knows a web request exists.
-
data
Talks to the store: the entities, the queries, the code that saves them.
-
adapter
The translator: it turns an outside service into a shape logic already understands.
-
shared
The small, boring things more than one folder needs: contracts, constants, helpers.
-
initializer
Startup wiring that runs once: configuration, dependencies, schema setup.
-
webhost
2. The Angular workspace
one folder per project: and the CLI decides what lives where
Angular's answer to "where does everything go?" is a workspace: a folder that
holds the shared configuration, one root application, and (if you ever need them) more
applications and libraries beside it. Almost every file at the top was written by the CLI, not
by you. All of your code hides one level down, in src.
-
my-app
workspace
-
.vscode
Editor settings the CLI writes for you: recommended extensions, formatting rules.
-
public
Assets served as-is at the site root: the favicon,
robots.txt, anything whose file name must survive the build untouched. Workspaces created before v17 kept these insrc/assets. -
src
The application itself: one entry point, one page, and the component tree under it.
-
app
Everything Angular knows as "the app": the root component, its routes, its providers, and a test beside each piece. The screens you build live one level down, in
features.-
features
Where the screens you build go: one folder per feature, named after the feature, so a screen is found by name instead of by hunting through a list of files.
-
hello
A generic feature, made with
ng generate component features/hello. The name is the whole point: everything this screen needs lives under this folder. The route table one level up, inapp.routes.ts, is what turns it into a URL.-
hello.ts
The component itself: the job the root component does, for one screen instead of the whole app. In workspaces created before v20 the same file was
hello.component.ts. -
hello.html
Its template, kept beside it: the same arrangement as
app.tsandapp.htmlone level up. -
hello.css
Styles for this component alone, scoped like every component's styles: nothing here can reach the root component or another feature.
-
hello.ts
-
hello
-
app.ts
The root component. It is
app.tssince v20; in older workspaces the same file wasapp.component.ts. -
app.html
That component's template, kept beside it rather than inlined.
-
app.css
Styles for that template only; they cannot leak out to the rest of the app.
-
app.config.ts
The providers the application starts with: the router, HTTP, change detection.
-
app.routes.ts
The route table: which URL loads which component.
-
app.spec.ts
The unit test for the root component, sitting beside the code it tests. Every component, service and pipe you generate arrives with a file like this.
-
features
-
index.html
The one page the browser loads. It contains
<app-root>and little else: the component tree is mounted into that tag. -
main.ts
The entry point, and it is one line of work:
bootstrapApplication(App, appConfig). -
styles.css
Global styles. Everything else in the app is styled per component and scoped to it.
-
app
-
angular.json
The workspace configuration: which entry file, which assets, which builder serves and tests every project in the folder. If a build behaves strangely, this is the first file to read.
-
package.json
The npm dependencies plus the
start,buildandtestscripts the CLI added for you. -
tsconfig.json
The base TypeScript settings.
tsconfig.app.jsonandtsconfig.spec.jsonextend it: one for the app, one for its tests. -
.editorconfig
Indentation and newline rules, so every editor in the team agrees.
-
.gitignore
Keeps
node_modules,distand the Angular cache out of source control. -
README.md
Generated, and mostly a cheat sheet of CLI commands.
-
.vscode
3. The React app
the same question, answered with a flat folder of files
A Vite + React project has no workspace file and nothing generated to hide behind. Everything
that matters sits in src, and the HTML page is an ordinary file at the top of the
project. Where Angular's entry point is TypeScript, React's is still HTML, and that single
difference explains most of what follows.
-
my-react-app
app
-
public
Files served as-is at the URL root, file name and all. Nothing in here is bundled or renamed.
-
vite.svg
The template's tab icon, reached as
/vite.svgand referenced by name from the page.
-
vite.svg
-
src
All of the code, one level down from the top: the same address Angular's code uses.
-
assets
Images that components import. Imported files get a hashed name at build time, which is exactly what never happens to anything in
public.-
react.svg
The React logo the template imports in
App.jsx.
-
react.svg
-
App.css
Styles imported by
App.jsx: one file, one component, no scoping machinery. -
App.jsx
The top component. In a React project this is the file to open first: it is the page, and everything you add hangs off it.
-
index.css
Global styles, loaded once for the whole page: the counterpart to
App.css. -
main.jsx
The entry point: it finds
<div id="root">and mounts<App />into it.
-
assets
-
index.html
The page itself, at the top of the project rather than buried in a source folder. It holds
<div id="root">and one<script type="module" src="/src/main.jsx">line: the seam between HTML and React. -
vite.config.js
A few lines of configuration: use the React plugin, and let Vite's defaults do the rest.
-
package.json
reactandreact-dom, plus thedev,buildandpreviewscripts. -
.oxlintrc.json
The lint rules the template ships today. Older copies of this same template call the file
eslint.config.js; both names mean the same row. -
.gitignore
Keeps
node_modulesanddistout of source control. -
README.md
Two paragraphs about the template, and the plugin it uses to compile JSX.
-
public
4. The iOS app
a project file you rarely open, and a source folder even Xcode now treats as plain
An Xcode project is two things wearing one name: a build description you almost never edit by
hand, and a folder of Swift. Since Xcode 16 that folder is a buildable folder:
every file in it belongs to the target, so there is no file list to maintain and adding a file
is just adding a file. There is no Info.plist in it either: Xcode synthesizes one
from build settings unless you deliberately point INFOPLIST_FILE at a plist of your
own.
-
MyApp
iOS app
-
MyApp.xcodeproj
One row in Finder, a folder underneath: this is the project itself, not a build output.
-
project.pbxproj
The build description: targets, files, build settings. Shared schemes live beside it in
xcshareddata/xcschemes.
-
project.pbxproj
-
MyApp
buildable folder
The app's own code. Everything here compiles into the app, and nothing here tells the project what to compile.
-
MyAppApp.swift
The entry point:
@main, oneWindowGroup, andContentViewas the first screen. -
ContentView.swift
The first screen, and the first file you will edit: a
Viewwhosebodyis made of stacks and text. -
Assets.xcassets
The asset catalog: colours, images and the app icon, compiled into the bundle at build time.
-
AppIcon.appiconset
One slot per icon size. Since Xcode 14 you supply a single 1024-pixel image here and the rest are generated.
-
AccentColor.colorset
The tint SwiftUI applies wherever you did not name a colour yourself.
-
AppIcon.appiconset
-
MyAppApp.swift
-
MyAppTests
The unit test target. A new Xcode 16 project writes this one with Swift Testing (
import Testing,@Testfunctions and#expect(…)), not XCTest.-
MyAppTests.swift
Nearly empty, and still the best place to see what a modern Swift test looks like.
-
MyAppTests.swift
-
MyAppUITests
The UI test target, and here the framework has not changed: these are still
XCTestCasesubclasses driving the app throughXCUIApplication.-
MyAppUITests.swift
Launches the app and works it the way a person would: tapping, typing, waiting.
-
MyAppUITestsLaunchTests.swift
Separate on purpose: it photographs the launch screen in each orientation, for every test run.
-
MyAppUITests.swift
-
MyApp.xcodeproj
5. The Android app
a module wrapped in build files, with Kotlin in a folder named java
An Android project is one app module surrounded by Gradle files. The Kotlin
lives under a folder called java, the package name is a real folder chain, and the
layout file that used to describe the screen is simply absent: a @Composable
function draws it instead.
-
MyApplication
Android app
-
app
module
The module that becomes the APK: its own build file, its own sources, its own tests.
-
src
Code, split by where it is expected to run.
-
main
What ships: the Kotlin, the resources, and the manifest that declares them.
-
java
Not a mistake: the Kotlin source set is still called
java, and Gradle compiles.ktfiles out of it without complaint.-
com/example/myapplication
The package name is a real folder chain (
com,example,myapplication), because each dot in a package maps to a directory.-
MainActivity.kt
The screen. One activity, whose
onCreatecallssetContent { … }: there is nores/layout/activity_main.xmlto inflate.
-
MainActivity.kt
-
com/example/myapplication
-
res
Everything that is a resource rather than code. Notice what is missing: there is no
layoutfolder, because a Compose screen is drawn in Kotlin.-
drawable
Vector artwork and shapes:
ic_launcher_background.xmlandic_launcher_foreground.xml. -
mipmap-…
Six folders collapsed into one row:
mipmap-anydpi-v26plus the fivemipmap-*dpidensities. A launcher icon per screen density, and the adaptive-icon XML that ties them together. -
values
colors.xml,strings.xml,themes.xml: the names the code and the manifest refer to instead of writing literals twice. -
xml
backup_rules.xmlanddata_extraction_rules.xml: what Auto Backup copies off the device, and what a device-to-device transfer carries over.
-
drawable
-
AndroidManifest.xml
The declaration the platform reads before any of your code runs: this is the app, this is its activity, this is the name and icon it shows.
-
java
-
test
Unit tests that run on the JVM: no device and no emulator.
-
ExampleUnitTest.kt
JUnit 4 and one piece of arithmetic, waiting to be replaced by the first real test.
-
ExampleUnitTest.kt
-
androidTest
Instrumented tests: these ones run on a device or an emulator.
-
ExampleInstrumentedTest.kt
Checks that the app is running under the package name it was built with.
-
ExampleInstrumentedTest.kt
-
main
-
build.gradle.kts
This module's build: the SDK versions it compiles against, the Compose feature flag, and the libraries only the app needs.
-
proguard-rules.pro
Rules for the shrinker that runs on release builds. Empty by default, and only touched when something gets stripped that should not have been.
-
src
-
gradle
What Gradle itself needs, so that a machine with no Gradle installed can still build the project.
-
libs.versions.toml
The version catalog, the row worth knowing about: every version, library and plugin is declared here once and referenced by alias from the build files, so a version number lives in exactly one place.
-
wrapper
Pins the Gradle version this project builds with, whatever is installed on the machine.
-
gradle-wrapper.jar
The small program the scripts hand control to; it reads the properties file and downloads the right Gradle.
-
gradle-wrapper.properties
One line of interest: the distribution URL that names the version.
-
gradle-wrapper.jar
-
libs.versions.toml
-
build.gradle.kts
The root build file: it declares the plugins the whole build uses and applies none of them; the module decides which it wants.
-
settings.gradle.kts
The module list and the repositories plugins are fetched from: the file that makes
libs.versions.tomlvisible everywhere. -
gradlew
The wrapper script for macOS and Linux.
-
gradlew.bat
The same script for Windows. Either way,
./gradlew buildis the one command to remember. -
local.properties
Generated by Android Studio and machine-specific: it points at your SDK. It is never committed, which is why it is missing from a fresh clone.
-
.gitignore
Keeps
build,.gradleandlocal.propertiesout of source control.
-
app
module