|
| 1 | +--- |
| 2 | +title: Getting started |
| 3 | +description: Tempest can be installed as a standalone PHP project, as well as a package within existing projects. The framework modules can also be installed individually, including in projects built on other frameworks. |
| 4 | +--- |
| 5 | + |
| 6 | +## Installation |
| 7 | + |
| 8 | +Tempest requires PHP [8.4+](https://www.php.net/downloads.php) and [Composer](https://getcomposer.org/) to be installed. Optionally, you may install either [Bun](https://bun.sh) or [Node](https://nodejs.org) if you chose to bundle front-end assets. |
| 9 | + |
| 10 | +For a better experience, it is recommended to have a complete development environment, such as [ServBay](https://www.servbay.com), [Herd](https://herd.laravel.com/docs), or [Valet](https://laravel.com/docs/valet). However, Tempest can serve applications using PHP's built-in server just fine. |
| 11 | + |
| 12 | +Once the prerequisites are installed, you can chose your installation method. Tempest can be a standalone application, or be added in an existing project—even one built on top of another framework. |
| 13 | + |
| 14 | +## Creating a Tempest application |
| 15 | + |
| 16 | +To get started with a new Tempest project, you may use {`tempest/app`} as the starting point. The `composer create-project` command will scaffold it for you: |
| 17 | + |
| 18 | +```sh |
| 19 | +composer create-project tempest/app my-app --stability alpha |
| 20 | +cd my-app |
| 21 | +``` |
| 22 | + |
| 23 | +If you have a dedicated development environment, you may then access your application by opening `https://my-app.test` in your browser. Otherwise, you may use PHP's built-in server: |
| 24 | + |
| 25 | +```sh |
| 26 | +php tempest serve |
| 27 | +# PHP 8.3.3 Development Server (http://localhost:8000) started |
| 28 | +``` |
| 29 | + |
| 30 | +### Scaffolding front-end assets |
| 31 | + |
| 32 | +Optionally, you may install a basic front-end scaffolding that includes [Vite](https://vite.dev/) and [Tailwind CSS](https://tailwindcss.com/). To do so, run the Vite installer and follow through the wizard: |
| 33 | + |
| 34 | +```sh |
| 35 | +php tempest install vite --tailwind |
| 36 | +``` |
| 37 | + |
| 38 | +<!-- TODO: docs --> |
| 39 | +The assets created by this wizard, `main.entrypoint.ts` and `main.entrypoint.css`, are automatically discovered by Tempest. You can serve them using the `<x-vite-tags />` component in your templates. |
| 40 | + |
| 41 | +You may then run the front-end development server, which will serve your assets on-the-fly: |
| 42 | + |
| 43 | +```bash |
| 44 | +npm run dev |
| 45 | +``` |
| 46 | + |
| 47 | +## Tempest as a package |
| 48 | + |
| 49 | +If you already have a project, you can opt to install {`tempest/framework`} as a standalone package. You could do this in any project; it could already contain code, or it could be an empty project. |
| 50 | + |
| 51 | +```sh |
| 52 | +composer require tempest/framework:1.0-alpha.5 |
| 53 | +``` |
| 54 | + |
| 55 | +Installing Tempest this way will give you access to the Tempest console, `./vendor/bin/tempest`. Optionally, you can choose to install Tempest's entry points in your project. To do so, you may run the framework installer: |
| 56 | + |
| 57 | +```txt |
| 58 | +./vendor/bin/tempest install framework |
| 59 | +``` |
| 60 | + |
| 61 | +This installer will prompt you to install the following files into your project: |
| 62 | + |
| 63 | +- `public/index.php` — the web application entry point |
| 64 | +- `tempest` – the console application entry point |
| 65 | +- `.env.example` – a clean example of a `.env` file |
| 66 | +- `.env` – the real environment file for your local installation |
| 67 | + |
| 68 | +You can choose which files you want to install, and you can always rerun the `install` command at a later point in time. |
| 69 | + |
| 70 | +## Project structure |
| 71 | + |
| 72 | +Tempest won't impose any file structure on you: one of its core features is that it will scan all project and package code for you, and will automatically discover any files the framework needs to know about. |
| 73 | + |
| 74 | +For instance, Tempest is able to differentiate between a controller method and a console command by looking at the code, instead of relying on naming conventions or configuration files. |
| 75 | + |
| 76 | +:::info |
| 77 | +This concept is called [discovery](../3-internals/02-discovery), and is one of Tempest's most powerful features. |
| 78 | +::: |
| 79 | + |
| 80 | +### Examples |
| 81 | + |
| 82 | +The following projects structures work the same way in Tempest, without requiring any specific configuration: |
| 83 | + |
| 84 | +```txt |
| 85 | +app |
| 86 | +├── Console |
| 87 | +│ └── RssSyncCommand.php |
| 88 | +├── Controllers |
| 89 | +│ ├── BlogPostController.php |
| 90 | +│ └── HomeController.php |
| 91 | +└── Views |
| 92 | + ├── blog.view.php |
| 93 | + └── home.view.php |
| 94 | +``` |
| 95 | + |
| 96 | +```txt |
| 97 | +src |
| 98 | +├── Blog |
| 99 | +│ ├── BlogPostController.php |
| 100 | +│ ├── RssSyncCommand.php |
| 101 | +│ └── blog.view.php |
| 102 | +└── Home |
| 103 | + ├── HomeController.php |
| 104 | + └── home.view.php |
| 105 | +``` |
| 106 | + |
| 107 | +From Tempest's perspective, it's all the same. |
| 108 | + |
| 109 | +## About Discovery |
| 110 | + |
| 111 | +Discovery works by scanning your project code, and looking at each file and method individually to determine what that code does. For production application, Tempest will cache the discovery process, avoiding any performance overhead. |
| 112 | + |
| 113 | +As an example, Tempest is able to determine which methods are controller methods based on their route attributes: |
| 114 | + |
| 115 | +```php app/BlogPostController.php |
| 116 | +use Tempest\Router\Get; |
| 117 | +use Tempest\Router\Response; |
| 118 | +use Tempest\View\View; |
| 119 | + |
| 120 | +final readonly class BlogPostController |
| 121 | +{ |
| 122 | + #[Get('/blog')] |
| 123 | + public function index(): View |
| 124 | + { /* … */ } |
| 125 | + |
| 126 | + #[Get('/blog/{post}')] |
| 127 | + public function show(Post $post): Response |
| 128 | + { /* … */ } |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +And likewise, it's able to detect console commands based on their console command attribute: |
| 133 | + |
| 134 | +```php src/RssSyncCommand.php |
| 135 | +use Tempest\Console\HasConsole; |
| 136 | +use Tempest\Console\ConsoleCommand; |
| 137 | + |
| 138 | +final readonly class RssSyncCommand |
| 139 | +{ |
| 140 | + use HasConsole; |
| 141 | + |
| 142 | + #[ConsoleCommand('rss:sync')] |
| 143 | + public function __invoke(bool $force = false): void |
| 144 | + { /* … */ } |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +### Discovery in production |
| 149 | + |
| 150 | +While discovery is a really powerful feature, it also comes with some performance considerations. In production environments, you want to make sure that the discovery workflow is cached. This is done by using the `DISCOVERY_CACHE` environment variable: |
| 151 | + |
| 152 | +```env .env |
| 153 | +{:hl-property:DISCOVERY_CACHE:}={:hl-keyword:true:} |
| 154 | +``` |
| 155 | + |
| 156 | +The most important step is to generate that cache. This is done by running the `discovery:generate`, which should be part of your deployment pipeline. Make sure to run it before any other Tempest command. |
| 157 | + |
| 158 | +```console |
| 159 | +~ ./tempest discovery:generate |
| 160 | + ℹ Clearing existing discovery cache… |
| 161 | + ✓ Discovery cached has been cleared |
| 162 | + ℹ Generating new discovery cache… (cache strategy used: all) |
| 163 | + ✓ Cached 1119 items |
| 164 | +``` |
| 165 | + |
| 166 | +### Discovery for local development |
| 167 | + |
| 168 | +By default, the discovery cache is disabled in local development. Depending on your local setup, it is likely that you will not run into noticeable slowdowns. However, for larger projects, you might benefit from enabling a partial discovery cache: |
| 169 | + |
| 170 | +```env .env |
| 171 | +{:hl-property:DISCOVERY_CACHE:}={:hl-keyword:partial:} |
| 172 | +``` |
| 173 | + |
| 174 | +This caching strategy will only cache discovery for vendor files. For this reason, it is recommended to run `discovery:generate` after every composer update: |
| 175 | + |
| 176 | +```json |
| 177 | +{:hl-comment:// …:} |
| 178 | + |
| 179 | +"scripts": { |
| 180 | + "post-package-update": [ |
| 181 | + "php tempest discovery:generate" |
| 182 | + ] |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +:::info |
| 187 | +Note that, if you've created your project using {`tempest/app`}, you'll have the `post-package-update` script already included. You may read the [internal documentation about discovery](../3-internals/02-discovery) to learn more. |
| 188 | +::: |
0 commit comments