-
Notifications
You must be signed in to change notification settings - Fork 7
Directory structure
Summary: The default structure of a StartER application is a starting point. You are free to organize your application however you like. StartER imposes no constraints on the location of an element, as long as you adapt the code to your organization: you have control!
StartER offers a robust, yet non-strict starting structure. The goal is to have a clear organization for your frontend and backend files, as well as the configuration.
.
├── .env
├── .env.sample
├── compose.yaml
├── compose.prod.yaml
├── Dockerfile
├── index.html
├── server.ts
├── data
│ ├── mailpit
│ └── sqlite
│ └── database.sqlite
└── src
├── entry-client.tsx
├── entry-server.tsx
├── database
│ └── schema.sql
├── express
│ ├── routes.ts
│ ├── helpers
│ │ └── ...
│ └── modules
│ └── ...
├── react
│ ├── routes.tsx
│ ├── helpers
│ │ └── ...
│ └── components
│ └── ...
└── types
└── index.d.ts
You can use the make:clone script provided with StartER to duplicate part of this structure and create new modules or components. This script does not impose any opinionated templates; it allows you to replicate your own structures and best practices.
StartER uses a .env file to separate environment variables from code. During a fresh installation of StartER, your application's root directory will contain a .env.sample file that defines common environment variables. This file serves as a common template for sharing necessary variables without exposing sensitive information. After installing StartER, copy this .env.sample file as .env.
cp .env.sample .envHere are the recommended variables that you should fill in with your own values:
| Variable | Description |
|---|---|
| APP_BASE_URL | Base URL of the application (used for magic links). |
| APP_SECRET | Secret key used to generate the signature for authentication |
| APP_PORT | (Optional) Port for the application server (5173 by default) |
| SMTP_URL | (Optional) SMTP URL for sending emails (e.g., smtp://mailpit:1025) |
A minimal version of your local .env file for development could look like this:
APP_BASE_URL=http://localhost:5173
APP_SECRET=18a7a18ac0db9b781836f82c080e1c82314b9b56b51f9a914c39cc41113280e8Note
Thanks to its Zero-Config architecture with SQLite, StartER does not require any complex configuration variables for the database.
Tip
To generate a robust APP_SECRET, you can use the following command in your terminal:
openssl rand -hex 32Also in your .env file, you can add:
- more variables for third-party tools you have installed,
- your own variables.
To start your application, StartER uses tsx (which uses the node command under the hood) with the --env-file option to load your .env file. Your variables are then available in process.env.
You can edit the tsx command options in the scripts in the package.json file at the root of the project.
{
"scripts": {
"dev": "tsx --env-file=.env server",
"start": "tsx --env-file=.env server",
...
},
...
}For example, you can pass multiple --env-file arguments to build a more complex configuration with multiple .env files (.env.local, .env.prod, etc.). Refer to the --env-file documentation for more details.
According to the official documentation:
Docker provides the ability to package and run an application in a loosely isolated environment called a container.
[...] A container is a runnable instance of an image.
[...] To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it.
A Dockerfile defines the contents and startup behavior of a single container. A StartER application image is based on an Alpine Linux image with the latest LTS version of Node.js pre-installed.
ARG NODE_VERSION=24
FROM node:${NODE_VERSION}-alpine
The Dockerfile copies your StartER application sources into this image, installs dependencies, and runs the npm run dev command.
COPY . .
# Run the application.
CMD ["npm", "run", "dev"]
The .dockerignore file excludes files not needed to build the image (such as README, LICENSE...).
Docker is optional but recommended. Additionally, a compose.yaml file allows you to define a multi-container application. In an isolated network, the StartER compose.yaml file defines:
- a
servercontainer for your StartER application, - a
mailpitcontainer to locally capture emails sent by the application (without complex configuration).
To create and start the containers in development mode, run the command:
docker compose up --buildMore options are available in the docker compose up documentation.
The compose.prod.yaml file specializes the containers for production:
- The
NODE_ENVenvironment variable is set toproduction. - The
servercontainer is started withnpm run build && npm start, rather thannpm run dev.
To create and start the containers in production mode, run the command:
docker compose -f compose.prod.yaml up --buildThe index.html file references entry-client and includes a <!--ssr-outlet--> tag where the server-rendered markup is injected (see explanation about the [one server] of StartER for details [warning: the page is more technical than the rest of the wiki]).
Also, the index.html file is the anchor point for Pico CSS by linking the library and adjusting some basic variables.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Start Express React</title>
<link
rel="shortcut icon"
href="/src/react/assets/images/favicon.png"
type="image/png"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<style>
:root {
--pico-border-radius: 2rem;
--pico-form-element-spacing-vertical: 0.5rem;
--pico-form-element-spacing-horizontal: 1rem;
}
</style>
</head>
<body>
<div class="container" id="root"><!--ssr-outlet--></div>
<script type="module" src="/src/entry-client"></script>
</body>
</html>Refer to the Pico CSS documentation for a list of available variables.
The server.ts file is the entry point to the framework. Its code bridges the gap between an Express server and a Vite server to create one server.
Most of your StartER application is hosted in the src directory. By default, the src directory contains the following directories:
-
database, -
express, -
react, -
types.
The express and react directories are the heart of your StartER application. They are organized in a similar way:
- A
helpersfolder contains infrastructure tools (cache, mutations, validation, converters). - A
modules(Express) orcomponents(React) folder contains your business logic and UI. - A
routesfile centralizes the registration of all endpoints or pages in the application.
The database directory contains your database schema (schema.sql), an optional seeder (seeder.sql) and the SQLite database declaration. The local database.sqlite database file generated on the fly will be hosted at the root of the project in the data/sqlite/ subdirectory.
The types directory contains the TypeScript type definitions shared throughout your StartER application.
These directories form the basis of your StartER application.
-
Share non-sensitive variables: you can include additional variables in your StartER application's
.env.samplefile. By adding entries to the.env.samplefile, other developers on your team can clearly identify the environment variables required to run your application. -
Never commit secrets: your
.envfile should never be added in a Git commit. Each workstation (local machine or server) running the application may require a different environment configuration. Furthermore, this would pose a critical security risk. -
Ignore your local data: the
data/directory containing your local database and mailpit emails is intentionally ignored by Git via the.gitignorefile. Do not commit it to avoid overwriting the local data of other developers.
AI co-creation
Getting started
Explanations
How-To Guides
Reference
Digging deeper